[BACK]Return to Todo.pm CVS log [TXT][DIR] Up to [local] / todotxt / Text-Todo / lib / Text

Diff for /todotxt/Text-Todo/lib/Text/Todo.pm between version 1.10 and 1.27

version 1.10, 2010/01/09 20:41:45 version 1.27, 2010/02/16 01:13:12
Line 1 
Line 1 
 package Text::Todo;  package Text::Todo;
   
 # $RedRiver: Todo.pm,v 1.9 2010/01/09 06:54:15 andrew Exp $  # $AFresh1: Todo.pm,v 1.26 2010/02/14 06:08:07 andrew Exp $
   
 use warnings;  use warnings;
 use strict;  use strict;
Line 10 
Line 10 
 use Text::Todo::Entry;  use Text::Todo::Entry;
 use File::Spec;  use File::Spec;
   
 use version; our $VERSION = qv('0.0.1');  use version; our $VERSION = qv('0.2.0');
   
 {  {
   
     my %path_of;      my @attr_refs = \(
     my %list_of;          my %path_of,
     my %loaded_of;  
   
           my %list_of,
           my %loaded_of,
           my %known_tags_of,
       );
   
     sub new {      sub new {
         my ( $class, $options ) = @_;          my ( $class, $options ) = @_;
   
Line 25 
Line 29 
         my $ident = ident($self);          my $ident = ident($self);
   
         $path_of{$ident} = {          $path_of{$ident} = {
             todo_dir    => undef,              todo_dir  => undef,
             todo_file   => 'todo.txt',              todo_file => 'todo.txt',
             done_file   => undef,              done_file => undef,
             report_file => undef,  
         };          };
   
           my %tags = (
               context => q{@},
               project => q{+},
           );
   
         if ($options) {          if ($options) {
             if ( ref $options eq 'HASH' ) {              if ( ref $options eq 'HASH' ) {
                 foreach my $opt ( keys %{$options} ) {                  foreach my $opt ( keys %{$options} ) {
                     if ( exists $path_of{$ident}{$opt} ) {                      if ( exists $path_of{$ident}{$opt} ) {
                         $self->_path_to( $opt, $options->{$opt} );                          $self->_path_to( $opt, $options->{$opt} );
                     }                      }
                       elsif ( $opt eq 'tags'
                           && ref $options->{$opt} eq 'HASH' )
                       {
                           %tags = ( %tags, %{ $options->{$opt} } );
                       }
                     else {                      else {
                         carp "Invalid option [$opt]";  
                           #carp "Invalid option [$opt]";
                     }                      }
                 }                  }
             }              }
Line 55 
Line 69 
             }              }
         }          }
   
           $known_tags_of{$ident} = \%tags;
   
         my $file = $self->_path_to('todo_file');          my $file = $self->_path_to('todo_file');
         if ( defined $file && -e $file ) {          if ( defined $file && -e $file ) {
             $self->load();              $self->load();
Line 134 
Line 150 
         $file = $self->file($file);          $file = $self->file($file);
   
         if ( $list_of{$ident} = $self->listfile($file) ) {          if ( $list_of{$ident} = $self->listfile($file) ) {
               $self->known_tags;
             $loaded_of{$ident} = $file;              $loaded_of{$ident} = $file;
             return 1;              return 1;
         }          }
Line 160 
Line 177 
         open my $fh, '<', $file or croak "Couldn't open [$file]: $!";          open my $fh, '<', $file or croak "Couldn't open [$file]: $!";
         while (<$fh>) {          while (<$fh>) {
             s/\r?\n$//xms;              s/\r?\n$//xms;
             next if !length $_;  
             push @list, Text::Todo::Entry->new($_);              push @list, Text::Todo::Entry->new($_);
         }          }
         close $fh or croak "Couldn't close [$file]: $!";          close $fh or croak "Couldn't close [$file]: $!";
Line 198 
Line 214 
     }      }
   
     sub listpri {      sub listpri {
         my ($self) = @_;          my ( $self, $pri ) = @_;
   
         my @list = grep { $_->priority } $self->list;          my @list;
           if ($pri) {
               $pri = uc $pri;
               if ( $pri !~ /^[A-Z]$/xms ) {
                   croak 'PRIORITY must a single letter from A to Z.';
               }
               @list = grep { defined $_->priority && $_->priority eq $pri }
                   $self->list;
           }
           else {
               @list = grep { $_->priority } $self->list;
           }
   
         return wantarray ? @list : \@list;          return wantarray ? @list : \@list;
     }      }
Line 210 
Line 237 
         my $ident = ident($self);          my $ident = ident($self);
   
         if ( !ref $entry ) {          if ( !ref $entry ) {
             $entry = Text::Todo::Entry->new($entry);              $entry = Text::Todo::Entry->new(
                   {   text => $entry,
                       tags => $known_tags_of{$ident},
                   }
               );
         }          }
         elsif ( ref $entry ne 'Text::Todo::Entry' ) {          elsif ( ref $entry ne 'Text::Todo::Entry' ) {
             croak(              croak(
Line 219 
Line 250 
   
         push @{ $list_of{$ident} }, $entry;          push @{ $list_of{$ident} }, $entry;
   
           $self->known_tags;
   
         return $entry;          return $entry;
     }      }
   
Line 250 
Line 283 
     }      }
   
     sub listproj {      sub listproj {
         my ( $self, $entry, $dst ) = @_;          my ($self) = @_;
           return $self->listtag('project');
       }
   
       sub listcon {
           my ($self) = @_;
           return $self->listtag('context');
       }
   
       sub listtag {
           my ( $self, $tag ) = @_;
         my $ident = ident($self);          my $ident = ident($self);
   
         my %available_projects;          my $accessor = $tag . 's';
   
           my %available;
         foreach my $e ( $self->list ) {          foreach my $e ( $self->list ) {
             foreach my $p ( $e->projects ) {              foreach my $p ( $e->$accessor ) {
                 $available_projects{$p} = 1;                  $available{$p} = 1;
             }              }
         }          }
   
         my @projects = sort keys %available_projects;          my @tags = sort keys %available;
   
         return wantarray ? @projects : \@projects;          return wantarray ? @tags : \@tags;
     }      }
   
       sub learn_tag {
           my ( $self, $tag, $sigal ) = @_;
   
           $known_tags_of{ ident $self}{$tag} = $sigal;
           $self->known_tags;
   
           return 1;
       }
   
       sub known_tags {
           my ($self) = @_;
           my $ident = ident($self);
   
           my @list = $self->list;
           my %tags = %{ $known_tags_of{$ident} };
   
           foreach my $e (@list) {
               my $kt = $e->known_tags;
               foreach my $t ( keys %{$kt} ) {
                   if ( !exists $tags{$t} ) {
                       $tags{$t} = $kt->{$t};
                   }
               }
           }
   
           foreach my $e (@list) {
               my $kt = $e->known_tags;
               foreach my $t ( keys %tags ) {
                   if ( !exists $kt->{$t} || $tags{$t} ne $kt->{$t} ) {
                       $e->learn_tag( $t, $tags{$t} );
                   }
               }
           }
   
           $known_tags_of{$ident} = \%tags;
   
           return $known_tags_of{$ident};
       }
   
     sub archive {      sub archive {
         my ($self) = @_;          my ($self) = @_;
         my $ident = ident($self);          my $ident = ident($self);
Line 276 
Line 360 
             return;              return;
         }          }
   
         my $archived = 0;          my $changed = 0;
     ENTRY: foreach my $e ( $self->list ) {      ENTRY: foreach my $e ( $self->list ) {
             if ( $e->done ) {              if ( $e->done ) {
                 if ( $self->addto( 'done_file', $e ) && $self->del($e) ) {                  if ( $self->addto( 'done_file', $e ) && $self->del($e) ) {
                     $archived++;                      $changed++;
                 }                  }
                 else {                  else {
                     carp q{Couldn't archive entry [} . $e->text . ']';                      carp q{Couldn't archive entry [} . $e->text . ']';
                     last ENTRY;                      last ENTRY;
                 }                  }
             }              }
               elsif ( $e->text eq q{} ) {
                   if ( $self->del($e) ) {
                       $changed++;
                   }
                   else {
                       carp q{Couldn't delete blank entry};
                       last ENTRY;
                   }
               }
         }          }
   
         if ($archived) {          if ($changed) {
             $self->save;              $self->save;
         }          }
   
         return $archived;          return $changed;
     }      }
   
     sub addto {      sub addto {
Line 351 
Line 444 
   
         croak "Invalid entry [$entry]!";          croak "Invalid entry [$entry]!";
     }      }
   
       sub DESTROY {
           my ($self) = @_;
           my $ident = ident $self;
   
           foreach my $attr_ref (@attr_refs) {
               delete $attr_ref->{$ident};
           }
   
           return;
       }
 }  }
   
 1;    # Magic true value required at end of module  1;    # Magic true value required at end of module
Line 358 
Line 462 
   
 =head1 NAME  =head1 NAME
   
 Text::Todo - Perl interface to todo_txt files  Text::Todo - Perl interface to todotxt files
   
   
 =head1 VERSION  =head1 VERSION
Line 439 
Line 543 
 then, $todo_file eq 'todo/todo.txt'  then, $todo_file eq 'todo/todo.txt'
   
 =head2 load  =head2 load
   - Reads a list from a file into the current object.
   
 Allows you to load a different file into the object.  Allows you to load a different file into the object.
   
Line 447 
Line 552 
 This effects the other functions that act on the list.  This effects the other functions that act on the list.
   
 =head2 save  =head2 save
   - Writes the list to disk.
   
     $todo->save(['new/path/to/todo']);      $todo->save(['new/path/to/todo']);
   
 Writes the list to the file. Either the current working file or something  Either writes the current working file or the passed in argument
 that can be recognized by file().  that can be recognized by file().
   
 If you specify a filename it will save to that file and update the paths.  If you specify a filename it will save to that file and update the paths.
 Additional changes to the object work on that file.  Additional changes to the object work on that file.
   
 =head2 list  =head2 list
   - get the curently loaded list
   
     my @todo_list = $todo->list;      my @todo_list = $todo->list;
   
   In list context returns a list, it scalar context returns an array reference to the list.
   
 =head2 listpri  =head2 listpri
   - get the list items that are marked priority
   
 Like list, but only returns entries that have priority set.  Like list, but only returns entries that have priority set.
   
     my @priority_list = $todo->listpri;      my @priority_list = $todo->listpri;
   
 =head2 listproj  Since this is so easy to write as:
   
 Returns projects in the list sorted by name.      my @priority_list = grep { $_->priority } $todo->list;
 If there were projects +GarageSale and +Shopping  
   
     my @projects = $todo->listproj;  I think it may become depreciated unless there is demand.
   
   =head2 known_tags
   
   Returns a reference to a hash of the tags known to the list.
   
   =head2 learn_tag($tag, $sigal)
   
   Let the entire list learn a new tag.
   If you are working with a list you should use this instead of
   $entry->learn_tag because it will update all entries.
   
   =head2 listtag($tag)
   
   Returns tags found in the list sorted by name.
   
   If there were projects +GarageSale and +Shopping then
   
       my @projects = $todo->listtag('project');
   
 is the same as  is the same as
   
     @projects = ( 'GarageSale', 'Shopping' );      @projects = ( 'GarageSale', 'Shopping' );
   
   =head2 listcon
   - Shortcut to listtag('context')
   
   =head2 listproj
   - Shortcut to listtag('project')
   
 =head2 add  =head2 add
   
 Adds a new entry to the list.  Adds a new entry to the list.
Line 566 
Line 699 
 =head1 BUGS AND LIMITATIONS  =head1 BUGS AND LIMITATIONS
   
 No bugs have been reported.  No bugs have been reported.
   
   Limitations:
   
   Currently there isn't an easy way to print out line numbers with the entry.
   
 Please report any bugs or feature requests to  Please report any bugs or feature requests to
 C<bug-text-todo@rt.cpan.org>, or through the web interface at  C<bug-text-todo@rt.cpan.org>, or through the web interface at

Legend:
Removed from v.1.10  
changed lines
  Added in v.1.27

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>