$heading$timestamp |
No matching task found.
\n\n"; } # Check whether to include overall statistics: if ($groups && $with_stats) { # Write statistics beginning: print FILE compose_statistics_header($groups, $tasks, $undone); # Process each group: foreach my $group (sort (keys %$stats)) { # Get the group statistics: my $group_done = $stats->{$group}->{done}; my $group_all = $stats->{$group}->{tasks}; # Count the percentage: my $percentage = int($group_done * 100 / $group_all); # Write the group progress entry: print FILE compose_statistics_entry($group, $percentage, $group_done, $group_all); } # Count the overall percentage: my $percentage = $tasks ? int($done * 100 / $tasks) : 0; # Write the overall progress entry: print FILE compose_statistics_entry('total', $percentage, $done, $tasks, 1); # Write statistics closing: print FILE compose_statistics_footer(); } # Write footer: print FILE compose_html_footer() unless $bare; # Close the outpt: close(FILE); } else { # Report failure: print STDERR "Unable to write to `$outfile'.\n"; # Return failure: return 0; } # Return success: return 1; } # Fix the group name: sub fix_group { my $group = shift || die 'Missing argument'; # Check whether it contains forbidden characters: if ($group =~ /:/) { # Display warning: print STDERR "Colon is not allowed in the group name. Removing.\n"; # Remove forbidden characters: $group =~ s/://g; } # Check the group name length: if (length($group) > 10) { # Display warning: print STDERR "Group name too long. Stripping.\n"; # Strip it to the maximal allowed length: $group = substr($group, 0, 10); } # Make sure the result is not empty: unless ($group) { # Display warning: print STDERR "Group name is empty. Using the default group instead.\n"; # Use default group instead: $group = 'general'; } # Return the result: return $group; } # Translate due date alias to YYYY-MM-DD string: sub translate_date { my $date = shift || die 'Missing argument'; # Translate the alias: if ($date =~ /^\d{4}-[01]\d-[0-3]\d$/) { return $date } elsif ($date eq 'anytime') { return $date } elsif ($date eq 'today') { return date_to_string(time) } elsif ($date eq 'yesterday') { return date_to_string(time - 86400) } elsif ($date eq 'tomorrow') { return date_to_string(time + 86400) } elsif ($date eq 'month') { return date_to_string(time + 2678400) } elsif ($date eq 'year') { return date_to_string(time + 31536000) } else { # Report failure and exit: exit_with_error("Invalid due date `$date'.", 22); } } # Translate due date alias to mask: sub translate_mask { my $date = shift; # Translate the alias: if ($date eq 'month') { return substr(date_to_string(time), 0, 8) . '..'; } elsif ($date eq 'year') { return substr(date_to_string(time), 0, 5) . '..-..'; } else { return translate_date($date); } } # Set up the option parser: Getopt::Long::Configure('no_auto_abbrev', 'no_ignore_case', 'bundling'); # Parse command line options: GetOptions( # General options: 'help|h' => sub { display_help(); exit 0 }, 'version|v' => sub { display_version(); exit 0 }, # Specifying options: 'task|t=s' => sub { $args{task} = $_[1] }, 'group|g=s' => sub { $args{group} = $_[1] }, 'date|d=s' => sub { $args{date} = $_[1] }, 'priority|p=i' => sub { $args{priority} = $_[1] }, 'finished|f' => sub { $args{state} = 't' }, 'unfinished|u' => sub { $args{state} = 'f' }, # Additional options: 'savefile|s=s' => sub { $savefile = $_[1] }, 'output|o=s' => sub { $outfile = $_[1] }, 'encoding|e=s' => sub { $encoding = $_[1] }, 'heading|H=s' => sub { $heading = $_[1] }, 'preserve|k' => sub { $preserve = 1 }, 'inline|i' => sub { $inline = 1 }, 'no-bare|B' => sub { $bare = 0 }, 'bare|b' => sub { $bare = 1 }, 'no-id|I' => sub { $with_id = 0 }, 'with-id' => sub { $with_id = 1 }, 'no-date|D' => sub { $with_date = 0 }, 'with-date' => sub { $with_date = 1 }, 'no-priority|P' => sub { $with_pri = 0 }, 'with-priority' => sub { $with_pri = 1 }, 'no-state|S' => sub { $with_state = 0 }, 'with-state' => sub { $with_state = 1 }, 'no-stats|no-stat' => sub { $with_stats = 0 }, 'stats|stat|with-stats' => sub { $with_stats = 1 }, ); # Detect superfluous options: if (scalar(@ARGV) != 0) { exit_with_error("Invalid option `$ARGV[0]'.", 22); } # Fix the group option: if (my $value = $args{group}) { $args{group} = fix_group($value); } # Translate the due date option: if (my $value = $args{date}) { $args{date} = translate_mask($value) } # Check the priority option: if (my $value = $args{priority}) { unless ($value =~ /^[1-5]$/) { exit_with_error("Invalid priority `$value'.", 22); } } # Force embedded style sheet when writing to STDOUT: if ($outfile eq '-') { $inline = 1; } # Write the HTML file: write_tasks(\%args) or exit 1; # Write the CSS file: write_style_sheet() or exit 1 if ($bare && !$inline); # Return success: exit 0; __END__ =head1 NAME w2html - a HTML exporter for w2do =head1 SYNOPSIS B