stas        02/03/21 18:01:52

  Modified:    lib      DocSet.pm
               lib/DocSet Config.pm Doc.pm DocSet.pm RunTime.pm Util.pm
               lib/DocSet/Doc Common.pm POD2HTML.pm POD2HTMLPS.pm
               lib/DocSet/DocSet HTML.pm PSPDF.pm
               lib/DocSet/Source POD.pm
  Log:
  sync with DocSet
  
  - The path must be either ./foo or ../../foo and never leading ./
    followed by ../, since the later doesn't work in IE on Mac.
  
  - partial implementation of L<> handling in POD according to the
    latest spec, submitted to Pod::POM and therefore now DocSet requires
    Pod::POM-0.15.
  
  - hyperlinks validation with -l option is implemented now.
  
  - implemented a RunTime system which allows to set/unset and retrieve
    the current rendering object, needed for implementing
    view_seq_link_transform_path() and view_seq_file() which need to use
    the rendering object.
  
  - implemented the view_seq_link_transform_path to locate the elements
    in L<> in the search path and properly resolve all the internal
    linking.
  
  - added the implementation of the F<> sequence via view_seq_file(),
    which links to a file if it finds it, otherwise it italize the path.
  
  - working on documenting a few classes
  
  - the templates now have an access to a new variable
    doc.dir.path_from_base which specifies the path from the root/base
    to the document without including the final file. ala
    File::Basename::dirname(), it doesn't include any leading ./ and
    closing / and originally developed for the searching sub-docsets.
  
  Revision  Changes    Path
  1.4       +2 -2      modperl-docs/lib/DocSet.pm
  
  Index: DocSet.pm
  ===================================================================
  RCS file: /home/cvs/modperl-docs/lib/DocSet.pm,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- DocSet.pm 5 Feb 2002 10:27:19 -0000       1.3
  +++ DocSet.pm 22 Mar 2002 02:01:51 -0000      1.4
  @@ -1,6 +1,6 @@
   package DocSet;
   
  -$VERSION = '0.11';
  +$VERSION = '0.12';
   
   =head1 NAME
   
  @@ -21,7 +21,7 @@
     -d    generate PDF file
     -f    force a complete rebuild
     -a    print available hypertext anchors (not implemented)
  -  -l    do hypertext links validation (not implemented)
  +  -l    perform L<> links validation in pod docs
     -e    slides mode (for presentations) (not implemented)
     -m    executed from Makefile (forces rebuild,
                                no PS/PDF file,
  
  
  
  1.5       +79 -55    modperl-docs/lib/DocSet/Config.pm
  
  Index: Config.pm
  ===================================================================
  RCS file: /home/cvs/modperl-docs/lib/DocSet/Config.pm,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- Config.pm 5 Feb 2002 10:27:19 -0000       1.4
  +++ Config.pm 22 Mar 2002 02:01:51 -0000      1.5
  @@ -5,11 +5,11 @@
   
   use Carp;
   
  -use File::Find;
   use File::Basename ();
   use File::Spec::Functions;
   
   use DocSet::Util;
  +use DocSet::RunTime ();
   
   use constant TRACE => 1;
   
  @@ -125,11 +125,63 @@
       # so this value is relevant only for the real top parent node
       $self->{dir}{abs_doc_root} = '.';
   
  +    $self->{dir}{path_from_base} ||= '';
  +
       $self->{dir}{src_root} = File::Basename::dirname $config_file;
  +
  +    if ($self->{dir}{search_paths}) {
  +        DocSet::RunTime::scan_src_docs($self->{dir}{src_root},
  +                                       $self->{dir}{search_paths},
  +                                       $self->{dir}{search_exts}
  +                                      );
  +    }
  +
       # dumper $self;
   
   }
   
  +# child config inherits parts from the parent config
  +# and adjusts its paths
  +sub merge_config {
  +    my($self, $src_rel_dir) = @_;
  +
  +    my $parent_o = $self->{parent_o};
  +
  +    # inherit 'file' attributes if not set in the child 
  +    my $files = $self->{file} || {};
  +    while ( my($k, $v) = each %{ $parent_o->{file}||{} }) {
  +        $self->{file}{$k} = $v unless $files->{$k};
  +    }
  +
  +    # inherit 'dir' attributes if not set in the child 
  +    my $dirs = $self->{dir} || {};
  +    while ( my($k, $v) = each %{ $parent_o->{dir}||{} }) {
  +        $self->{dir}{$k} = $v unless $dirs->{$k};
  +    }
  +
  +    # a chapter object won't set this one
  +    if ($src_rel_dir) {
  +        $self->{dir}{src_rel_dir} = $src_rel_dir;
  +
  +        # append the relative to parent_o's src dir segments
  +        # META: hardcoded paths!
  +        for my $k ( qw(dst_html dst_ps dst_split_html) ) {
  +            $self->{dir}{$k} .= "/$src_rel_dir";
  +        }
  +
  +        # only path with no leading ./ or closing /
  +        $self->{dir}{path_from_base} = join "/", grep /./,
  +            $self->{dir}{path_from_base}, $src_rel_dir;
  +
  +        # set path to the abs_doc_root 
  +        # META: hardcoded paths! (but in this case it doesn't matter,
  +        # as long as it's set in the config file
  +        $self->{dir}{abs_doc_root} = 
  +            join '/', ("..") x ($self->{dir}{dst_html} =~ tr|/|/|);
  +    }
  +
  +}
  +
   
   # this sub controls the docset's 'modified' attribute which specifies
   # whether the docset is in a "dirty" state and need to be rebuilt or
  @@ -178,43 +230,6 @@
       return scalar @values;
   }
   
  -# child config inherits parts from the parent config
  -# and adjusts its paths
  -sub merge_config {
  -    my($self, $src_rel_dir) = @_;
  -
  -    my $parent_o = $self->{parent_o};
  -
  -    # inherit 'file' attributes if not set in the child 
  -    my $files = $self->{file} || {};
  -    while ( my($k, $v) = each %{ $parent_o->{file}||{} }) {
  -        $self->{file}{$k} = $v unless $files->{$k};
  -    }
  -
  -    # inherit 'dir' attributes if not set in the child 
  -    my $dirs = $self->{dir} || {};
  -    while ( my($k, $v) = each %{ $parent_o->{dir}||{} }) {
  -        $self->{dir}{$k} = $v unless $dirs->{$k};
  -    }
  -
  -    # a chapter object won't set this one
  -    if ($src_rel_dir) {
  -        $self->{dir}{src_rel_dir} = $src_rel_dir;
  -
  -        # append the relative to parent_o's src dir segments
  -        # META: hardcoded paths!
  -        for my $k ( qw(dst_html dst_ps dst_split_html) ) {
  -            $self->{dir}{$k} .= "/$src_rel_dir";
  -        }
  -
  -        # set path to the abs_doc_root 
  -        # META: hardcoded paths! (but in this case it doesn't matter,
  -        # as long as it's set in the config file
  -        $self->{dir}{abs_doc_root} = 
  -            join '/', ("..") x ($self->{dir}{dst_html} =~ tr|/|/|);
  -    }
  -
  -}
   
   # return a list of files potentially to be copied
   #
  @@ -265,22 +280,6 @@
   
   }
   
  -sub expand_dir {
  -    my @files = ();
  -    if ($] >= 5.006) {
  -       find(sub {push @files, $File::Find::name}, $_[0]);
  -    }
  -    else {
  -        # perl 5.005.03 on FreeBSD doesn't set the dir it chdir'ed to
  -        # need to move this to compat level?
  -        require Cwd;
  -        my $cwd;
  -        find(sub {$cwd = Cwd::cwd(); push @files, catfile $cwd, $_}, $_[0]);
  -    }
  -
  -    return [EMAIL PROTECTED];
  -}
  -
   sub set {
       my($self, %args) = @_;
       @{$self}{keys %args} = values %args;
  @@ -308,8 +307,20 @@
   
   sub get_dir {
       my $self = shift;
  +
       return () unless @_;
  -    my @values = map {exists $self->{dir}{$_} ? $self->{dir}{$_} : ''} @_;
  +
  +    my @values = ();
  +    for (@_) {
  +        if (exists $self->{dir}{$_}) {
  +            push @values, $self->{dir}{$_}
  +        }
  +        else {
  +            cluck "no entry for dir: $_";
  +            push @values, '';
  +        }
  +    }
  +
       return wantarray ? @values : $values[0];
   }
   
  @@ -541,6 +552,17 @@
                # location of the templates relative to the root dir
                # (searched left to right)
                tmpl       => [qw(tmpl/custom tmpl/std tmpl)],
  +
  +             # search path for pods, etc. must put more specific paths first!
  +             search_paths => [qw(
  +                 docs/2.0/api/mod_perl-2.0
  +                 docs/2.0/api/ModPerl-Registry
  +                 docs/2.0
  +                 docs/1.0
  +             )],
  +             # what extensions to search for
  +             search_exts => [qw(pod pm html)],
  +
            },  
   
   =item * file
  @@ -751,6 +773,8 @@
   
   META: does copy_skip apply to all sub-docsets, if sub-docsets specify
   their own copy_glob?
  +
  +Make sure to escape C</> chars.
   
   =back
   
  
  
  
  1.4       +35 -2     modperl-docs/lib/DocSet/Doc.pm
  
  Index: Doc.pm
  ===================================================================
  RCS file: /home/cvs/modperl-docs/lib/DocSet/Doc.pm,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Doc.pm    30 Jan 2002 16:55:04 -0000      1.3
  +++ Doc.pm    22 Mar 2002 02:01:51 -0000      1.4
  @@ -2,8 +2,12 @@
   
   use strict;
   use warnings;
  +
   use DocSet::Util;
  +use DocSet::RunTime;
  +
   use URI;
  +use File::Spec::Functions;
   
   sub new {
       my $class = shift;
  @@ -42,9 +46,12 @@
       $abs_doc_root .= "/$rel_doc_root"
           if defined $rel_doc_root and $rel_doc_root ne '.';
   
  +    $abs_doc_root =~ s|^./||; # IE/Mac can't handle path ./../foo
  +
       $self->{dir} = {
  -        abs_doc_root => $abs_doc_root,
  -        rel_doc_root => $rel_doc_root,
  +        abs_doc_root   => $abs_doc_root,
  +        rel_doc_root   => $rel_doc_root,
  +        path_from_base => $self->{path_from_base},
       };
   
       $self->{nav} = DocSet::NavigateCache->new($cache->path, $src_uri);
  @@ -115,6 +122,21 @@
       }
   }
   
  +# search for the source doc with base $base, and resolve it to a relative 
  +# to abs_doc_root path and return it 
  +# if not found return undef
  +sub transform_src_doc {
  +    my($self, $path) = @_;
  +
  +    if (my $path = find_src_doc($path)) {
  +        my $path = catfile $self->{dir}{abs_doc_root}, $path;
  +        $path =~ s|/\./|/|; # avoid .././foo links.
  +        return $path;
  +    }
  +
  +    return undef;
  +}
  +
   
   # abstract methods
   #sub src_filter {}
  @@ -170,6 +192,7 @@
   
   Fetches the source of the document. The source can be read from
   different media, i.e. a file://, http://, relational DB or OCR :)
  +(but these are left for subclasses to implement :)
   
   A subclass may implement a "source" filter. For example if the source
   document is written in an extended POD the source filter may convert
  @@ -186,6 +209,16 @@
   =item * toc
   
   a simple set/get-able accessor to the I<toc> attribute
  +
  +=item * transform_src_doc
  +
  +  my $doc_src_path = $self->transform_src_doc($path);
  +
  +search for the source doc with path of C<$path> at the search paths
  +defined by the configuration file I<search_paths> attribute (similar
  +to the C<@INC> search in Perl) and if found resolve it to a relative
  +to C<abs_doc_root> path and return it. If not found return the
  +C<undef> value.
   
   =back
   
  
  
  
  1.5       +18 -14    modperl-docs/lib/DocSet/DocSet.pm
  
  Index: DocSet.pm
  ===================================================================
  RCS file: /home/cvs/modperl-docs/lib/DocSet/DocSet.pm,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- DocSet.pm 5 Feb 2002 10:27:19 -0000       1.4
  +++ DocSet.pm 22 Mar 2002 02:01:51 -0000      1.5
  @@ -81,6 +81,9 @@
                               $rel_dir);
           $self->set_dir(rel_parent_root => $rel_dir);
       }
  +    else {
  +        $self->set_dir(rel_parent_root => '.');
  +    }
   
       ###
       # scan the nodes of the current level and cache the meta and other
  @@ -199,12 +202,12 @@
       my $src_root      = $self->get_dir('src_root');
       my $dst_root      = $self->get_dir('dst_root');
       my $abs_doc_root  = $self->get_dir('abs_doc_root');
  -    my $src_path      = "$src_root/$src_file",
  +    my $src_path      = "$src_root/$src_file";
   
       my $src_ext = filename_ext($src_file)
  -        or die "cannot get an extension for $src_file";
  +        or die "cannot get an extension for $src_file [$src_path]";
       my $src_mime = $self->ext2mime($src_ext)
  -        or die "unknown extension: $src_ext";
  +        or die "unknown extension: $src_ext [$src_path]";
       (my $basename = $src_file) =~ s/\.$src_ext$//;
   
       # destination paths
  @@ -233,17 +236,18 @@
       require_package($conv_class);
   
       my $chapter = $conv_class->new(
  -         docset       => $self,
  -         tmpl_mode    => $self->get('tmpl_mode'),
  -         tmpl_root    => $self->get_dir('tmpl'),
  -         src_root     => $src_root,
  -         dst_root     => $dst_root,
  -         src_uri      => $src_file,
  -         src_path     => $src_path,
  -         dst_path     => $dst_path,
  -         rel_dst_path => $rel_dst_path,
  -         rel_doc_root => $rel_doc_root,
  -         abs_doc_root => $abs_doc_root,
  +         docset         => $self,
  +         tmpl_mode      => $self->get('tmpl_mode'),
  +         tmpl_root      => $self->get_dir('tmpl'),
  +         src_root       => $src_root,
  +         dst_root       => $dst_root,
  +         src_uri        => $src_file,
  +         src_path       => $src_path,
  +         dst_path       => $dst_path,
  +         rel_dst_path   => $rel_dst_path,
  +         rel_doc_root   => $rel_doc_root,
  +         abs_doc_root   => $abs_doc_root,
  +         path_from_base => $self->get_dir('path_from_base'),
           );
   
       $chapter->scan();
  
  
  
  1.2       +204 -7    modperl-docs/lib/DocSet/RunTime.pm
  
  Index: RunTime.pm
  ===================================================================
  RCS file: /home/cvs/modperl-docs/lib/DocSet/RunTime.pm,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- RunTime.pm        5 Jan 2002 18:51:58 -0000       1.1
  +++ RunTime.pm        22 Mar 2002 02:01:51 -0000      1.2
  @@ -1,12 +1,30 @@
   package DocSet::RunTime;
   
  +# META: this class acts as Singleton, consider to actually use
  +# Class::Singleton
  +
   use strict;
   use warnings;
   
  +use File::Spec::Functions;
  +use File::Find;
  +
  +use DocSet::Util;
  +use Carp;
  +
   use vars qw(@ISA @EXPORT %opts);
   @ISA    = qw(Exporter);
  [EMAIL PROTECTED] = qw(get_opts);
  [EMAIL PROTECTED] = qw(get_opts find_src_doc set_render_obj get_render_obj 
unset_render_obj);
   
  +my %src_docs;
  +my %exts;
  +my $render_obj;
  +
  +# = (
  +#          'docs/2.0' => {
  +#                         'devel/core_explained/core_explained.pod' => 1,
  +#                        },
  +#         );
   
   sub set_opt {
       my(%args) = ();
  @@ -57,6 +75,75 @@
       return 0;
   }
   
  +sub scan_src_docs {
  +    my($base, $ra_search_paths, $ra_search_exts) = @_;
  +
  +    %exts = map {$_ => 1} @{$ra_search_exts || []};
  +
  +    my @ext_accept_pattern = map {quotemeta($_)."\$"} keys %exts;
  +    my $rsub_keep_ext = 
  +        build_matchmany_sub([EMAIL PROTECTED]);
  +
  +    my %seen;
  +    for my $rel_path (@{$ra_search_paths || []}) {
  +        my $full_path = catdir $base, $rel_path;
  +        die "$full_path is not a dir" unless -d $full_path;
  +
  +        my @seen_pattern = map {"^".quotemeta($_)} keys %seen;
  +        my $rsub_skip_seen = 
  +            build_matchmany_sub([EMAIL PROTECTED]);
  +
  +        $src_docs{$rel_path} = {
  +            map { $_ => 1 }
  +                map {s|$full_path/||; $_}
  +                grep $rsub_keep_ext->($_),   # get files with wanted exts
  +                grep !$rsub_skip_seen->($_), # skip seen base dirs
  +                @{ expand_dir($full_path) }
  +        };
  +
  +        note "Scanning for src files: $full_path";
  +        $seen{$full_path}++;
  +    }
  +
  +    #dumper \%src_docs;
  +}
  +
  +sub find_src_doc {
  +    my($resource_rel_path) = @_;
  +
  +    for my $path (keys %src_docs) {
  +        for my $ext (keys %exts) {
  +#print qq{Try:  $path :: $resource_rel_path.$ext\n};
  +            if (exists $src_docs{$path}{"$resource_rel_path.$ext"}) {
  +#print qq{Found $path/$resource_rel_path.$ext\n};
  +                return join '/', $path, "$resource_rel_path.$ext";
  +            }
  +
  +        }
  +    }
  +
  +}
  +
  +# set render object: sort of Singleton, it'll complain aloud if the
  +# object is set over the existing object, without first unsetting it
  +sub set_render_obj {
  +    Carp::croak("usage: set_render_obj(\$obj) ") unless @_;
  +    Carp::croak("unset render_obj before setting a new one") if $render_obj;
  +    Carp::croak("undefined render_obj passed") unless defined $_[0];
  +    $render_obj = shift;
  +}
  +
  +sub get_render_obj { 
  +    Carp::croak("render_obj is not available") unless $render_obj;
  +
  +    return $render_obj;
  +}
  +
  +sub unset_render_obj {
  +    Carp::croak("render_obj is not set") unless $render_obj;
  +
  +    undef $render_obj;
  +}
   
   1;
   __END__
  @@ -68,34 +155,57 @@
   =head1 SYNOPSIS
   
     use DocSet::RunTime;
  +
  +  # run time options
  +  DocSet::RunTime::set_opt(\%args);
     if (get_opts('verbose') {
         print "verbose mode";
     }
   
  -  DocSet::RunTime::set_opt(\%args);
  -
  +  # hosting system capabilities testing
     DocSet::RunTime::has_storable_module();
     DocSet::RunTime::can_create_ps();
     DocSet::RunTime::can_create_pdf();
   
  +  # source documents lookup
  +  DocSet::RunTime::scan_src_docs($base_path, [EMAIL PROTECTED], [EMAIL 
PROTECTED]);
  +  my $full_src_path = find_src_doc($resource_rel_path);
  +
  +  # rendering object singleton
  +  set_render_obj($obj);
  +  unset_render_obj();
  +  $obj = get_render_obj();
   
   =head1 DESCRIPTION
   
   This module is a part of the docset application, and it stores the run
  -time arguments. i.e. whether to build PS and PDF or to run in a
  -verbose mode and more.
  +time arguments, caches results of expensive calls and provide
  +Singleton-like service to the whole system.
   
   =head1 FUNCTIONS
   
   META: To be completed, see SYNOPSIS 
   
  +=head2 Run Time Options
  +
  +Only get_opts() method is exported by default.
  +
   =over
   
  -=item * set_opt
  +=item * set_opt(\%args)
  +
  +
  +=item * get_opts()
  +
   
  +=back
   
  -=item * get_opts
  +=head2 Hosting System Capabilities Testing
   
  +These methods test the capability of the system and are a part of the
  +runtime system to perform the checking only once.
  +
  +=over
   
   =item * has_storable_module
   
  @@ -105,6 +215,93 @@
   
   =item * can_create_pdf
   
  +=back
  +
  +=head2 Source Documents Lookup
  +
  +A system for mapping L<> escapes to the located of the rendered
  +files. This system scans once the C<@search_paths> for files with
  +C<@search_exts> starting from C<$base_path> using scan_src_docs(). The
  +C<@search_paths> and C<@search_exts> are configured in the
  +I<config.cfg> file. For example:
  +
  +    dir => {
  +             # search path for pods, etc. must put more specific paths first!
  +             search_paths => [qw(
  +                 foo/bar
  +                 foo
  +                 .
  +             )],
  +             # what extensions to search for
  +             search_exts => [qw(pod pm html)],
  +         },  
  +
  +So for example if the base path is I<~/myproject/src>, the files with
  +extensions I<.pod>, I<.pm> and I<.html> will be searched in
  +I<~/myproject/src/foo/bar>, I<~/myproject/src/foo> and
  +I<~/myproject/src>.
  +
  +Notice that you must specify the more specific paths first, since for
  +optimization the seen paths are skipped. Therefore in our example the
  +more explicit path I<foo/bar> was listed before the more general
  +I<foo>.
  +
  +When the POD parser finds a L<> sequence it indentifies the resource
  +part and passes it to the find_src_doc() which looks up for this file
  +in the cache and returns its original (src) location, which can be
  +then easily converted to the final location and optionally adjusting
  +the extension, e.g. when the POD file is converted to HTML.
  +
  +Only the find_src_doc() function is exported by default.
  +
  +=over
  +
  +=item * scan_src_docs($base_path, [EMAIL PROTECTED], [EMAIL PROTECTED]);
  +
  +=item * find_src_doc($resource_rel_path);
  +
  +
  +=back
  +
  +
  +=head2 Rendering Object Singleton
  +
  +Since the rendering process may happen by a third party system, into
  +which we provide hooks or overload some of its methods, it's quite
  +possible that we won't be able to access the current document (or
  +better rendering) object. One solution would be to have a global
  +package variable, but that's very error-prone. Therefore the used
  +solution is to provide a hook into a RunTime environment setting the
  +current rendering object when the rendering of a single page starts
  +via C<set_render_obj($obj)> and unsetting it when it's finished via
  +unset_render_obj(). Between these two moments the current rendering
  +object can be retrieved with get_render_obj() method.
  +
  +Notice that this is all possible in the program which is not threaded,
  +or/and only one rendering process exists at any given time from its
  +start to its end.
  +
  +All three methods are exported by default.
  +
  +=over
  +
  +=item * set_render_obj($obj)
  +
  +Sets the current rendering object.
  +
  +You cannot set a new rendering object before the previous one is
  +unset. This is in order to make sure that one document won't use by
  +mistake a rendering object of another document. So when the rendering
  +is done remember to call the unset_render_obj() function.
  +
  +=item * unset_render_obj()
  +
  +Unsets the currently set rendering object.
  +
  +=item * get_render_obj()
  +
  +Retrieves the currently set rendering object or complains aloud if it
  +cannot find one.
   
   =back
   
  
  
  
  1.4       +41 -6     modperl-docs/lib/DocSet/Util.pm
  
  Index: Util.pm
  ===================================================================
  RCS file: /home/cvs/modperl-docs/lib/DocSet/Util.pm,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Util.pm   5 Feb 2002 10:27:19 -0000       1.3
  +++ Util.pm   22 Mar 2002 02:01:51 -0000      1.4
  @@ -7,11 +7,12 @@
   use File::Basename ();
   use File::Copy ();
   use File::Path ();
  +use File::Find ();
   use Data::Dumper;
   use Carp;
   use Template;
   
  -use DocSet::RunTime;
  +require DocSet::RunTime; # interdependency with DocSet::Util
   
   use vars qw(@ISA @EXPORT);
   @ISA    = qw(Exporter);
  @@ -19,7 +20,7 @@
                create_dir filename filename_ext require_package dumper
                sub_trace note get_date get_timestamp proc_tmpl
                build_matchmany_sub banner should_update confess cluck
  -             format_bytes);
  +             carp format_bytes expand_dir);
   
   # copy_file($src_path, $dst_path);
   # copy a file at $src_path to $dst_path, 
  @@ -190,12 +191,14 @@
   sub should_update {
       my($src_path, $dst_path) = @_;
   
  +    die "cannot find $src_path" unless -e $src_path;
  +
       # to rebuild or not to rebuild
       my $not_modified = 
           (-e $dst_path and -M $dst_path < -M $src_path) ? 1 : 0;
   
       my $reason = $not_modified ? 'not modified' : 'modified';
  -    if (get_opts('rebuild_all')) {
  +    if (DocSet::RunTime::get_opts('rebuild_all')) {
           return (1, "$reason / forced");
       } else {
           return (!$not_modified, $reason);
  @@ -253,6 +256,22 @@
     }
   }
   
  +sub expand_dir {
  +    my @files = ();
  +    if ($] >= 5.006) {
  +       File::Find::find(sub {push @files, $File::Find::name}, $_[0]);
  +    }
  +    else {
  +        # perl 5.005_03 on FreeBSD doesn't set the dir it chdir'ed to
  +        # need to move this to compat level?
  +        require Cwd;
  +        my $cwd;
  +        File::Find::find(sub {$cwd = Cwd::cwd(); push @files, catfile $cwd, 
$_}, $_[0]);
  +    }
  +
  +    return [EMAIL PROTECTED];
  +}
  +
   
   sub dumper {
       print Dumper @_;
  @@ -266,15 +285,21 @@
   #}
   
   *confess = \*Carp::confess;
  -*cluck = \*Carp::cluck;
  +*cluck   = \*Carp::cluck;
  +*carp    = \*Carp::carp;
   
   sub note {
  -    return unless get_opts('verbose');
  +    return unless DocSet::RunTime::get_opts('verbose');
       print join("\n", @_), "\n";
  -
   }
   
   
  +#sub error {
  +#    return unless DocSet::RunTime::get_opts('verbose');
  +#    cluck(join("\n", @_), "\n");
  +#}
  +
  +
   1;
   __END__
   
  @@ -344,11 +369,21 @@
   
   =item * build_matchmany_sub
   
  +Since the patterns are compiled by insertion into m//, make sure that
  +any C</> are escaped. Be careful with using quotemeta() for this,
  +since you don't want to espace special regex char, e.g. C<^>, C<$>,
  +etc.
  +
   =item * dumper
   
   =item * confess
   
  +=item * cluck
  +
  +=item * carp
  +
   =item * note
  +
   
   =back
   
  
  
  
  1.3       +124 -48   modperl-docs/lib/DocSet/Doc/Common.pm
  
  Index: Common.pm
  ===================================================================
  RCS file: /home/cvs/modperl-docs/lib/DocSet/Doc/Common.pm,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Common.pm 7 Feb 2002 08:43:40 -0000       1.2
  +++ Common.pm 22 Mar 2002 02:01:51 -0000      1.3
  @@ -93,62 +93,38 @@
       return \%src;
   }
   
  +sub pod_pom_html_view_seq_link_transform_path {
  +    my($self, $path) = @_;
   
  -# These are POD::POM functions
  -sub pod_pom_html_view_seq_link {
  -    my ($self, $link) = @_;
  -#dumper $link;
  -#print "$link\n";
  -    # full-blown URL's are emitted as-is
  -    if ($link =~ m{^\w+://}s ){
  -        return make_href($link);
  -    }
  -
  -    $link =~ s/\n/ /g;   # undo word-wrapped tags
  -
  -    my $orig_link = $link;
  -    my $linktext;
  -    # strip the sub-title and the following '|' char
  -    if ( $link =~ s/^ ([^|]+) \| //x ) {
  -        $linktext = $1;
  -    }
  -    
  -    # make sure sections start with a /
  -    $link =~ s|^"|/"|;
  -
  -    my $page;
  -    my $section;
  -    if ($link =~ m|^ (.*?) / "? (.*?) "? $|x) { # [name]/"section"
  -        ($page, $section) = ($1, $2);
  -    }
  -    elsif ($link =~ /\s/) {  # this must be a section with missing quotes
  -        ($page, $section) = ('', $link);
  -    }
  -    else {
  -        ($page, $section) = ($link, '');
  -    }
  +    $path =~ s|::|/|g;
  +    my $doc_obj = get_render_obj();
   
  -    # warning; show some text.
  -    $linktext = $orig_link unless defined $linktext;
  +    my $res_path = $doc_obj->transform_src_doc($path);
  +    unless ($res_path) {
  +        # report broken links if we were told to
  +        if (DocSet::RunTime::get_opts('validate_links')) {
  +            print "!!! Broken link $doc_obj->{src_path}: [$path]\n";
  +        }
  +        return undef;
  +    }
  +
  +    $res_path =~ s/\.[^.]+$/.html/;
  +#    print "$res_path\n";
  +    return $res_path;
  +}
   
  -    my $url = '';
  -    if (defined $page && length $page) {
  -        $url = "$page.html";
  -        $url =~ s|::|/|g;
  -    }
   
  -    # append the #section if exists
  -    $url .= "#$section" if defined $section and length $section;
  +#sub make_href {
  +#    my($url, $title) = @_;
   
  -    return make_href($url, $linktext);
  -}
  +#    if (!defined $url) {
  +#        return defined $title ? "<i>$title</i>"  : '';
  +#    }
   
  -sub make_href {
  -    my($url, $title) = @_;
  -#print "$url, $title\n";
   #    $title = $url unless defined $title;
  +#print "$url, $title\n";
   #    return qq{<a href="$url">$title</a>};
  -}
  +#}
   
   sub pod_pom_html_anchor {
       my($self, $title) = @_;
  @@ -188,5 +164,105 @@
   }
   
   
  +
  +
   1;
   __END__
  +
  +=head1 NAME
  +
  +C<DocSet::Doc::Common> - Common functions used in C<DocSet::Doc> subclasses
  +
  +=head1 SYNOPSIS
  +
  +...
  +
  +=head1 DESCRIPTION
  +
  +Implements functions and bits of code which otherwise needed to be
  +duplicated in many modules. These functions couldn't be put into the
  +base class C<DocSet::Doc>. Certainly we could devise one more
  +subclassing level but for now this gentle mix of inheritance and
  +inclusion is doing its job just fine.
  +
  +=head1 METHODS
  +
  +=over
  +
  +=item * postprocess_ps_pdf
  +
  +  $self->postprocess_ps_pdf()
  +
  +renders ps and pdf version of a the current doc
  +
  +=item * fetch_pdf_doc_ver
  +
  +  %pdf_data = %{ $self->fetch_pdf_doc_ver() }
  +
  +search for a pdf version of the same document in the parallel tree
  +(usually the I<dst_html> tree) and copy+gzip it to the same dir as the
  +html version. Later we link to it from the html version of the
  +document if the pdf version is found in the same directory as the html
  +one.
  +
  +The function returns a reference to a hash with the keys: I<size> --
  +for the size of the gzipped file and the location of the file relative
  +to the current document (it's in the same directory after all).
  +
  +=item * fetch_src_doc_ver
  +
  +similar to fetch_pdf_doc_ver() but works with the source version of
  +the document.
  +
  +  %src_data = %{ $self->fetch_src_doc_ver() }
  +
  +fetch the source version of the same document in the parallel tree
  +(usually the I<src> tree) and copy+gzip it to the same dir as the html
  +version. Later we link to it from the html version of the document if
  +the source version is found in the same directory as the html one.
  +
  +The function returns a reference to a hash with the keys: I<size> --
  +for the size of the gzipped file and the location of the file relative
  +to the current document (it's in the same directory after all).
  +
  +=item * pod_pom_html_view_seq_link_transform_path
  +
  +  my $linked_doc_path = 
  +      $self->pod_pom_html_view_seq_link_transform_path($src_path)
  +
  +this is an implementation of the view_seq_link_transform_path()
  +callback used in C<Pod::POM::HTML::view_seq_link()>, using the
  +C<DocSet::Doc>'s transform_src_doc() method over pre-scanned cache of
  +the source documents the C<$src_path> is resolved into the path in the
  +generated docset. So for example a the resource C<devel::help> in
  +LE<lt>devel help doc|devel::helpL<gt> could get resolved as
  +I<mydocs/devel/help.html>. For more info see the documentation for
  +C<DocSet::Doc::transform_src_doc()>.
  +
  +Notice that since this method is a callback hook, it uses the runtime
  +singleton function C<DocSet::RunTime::get_render_obj()> to retrieve
  +the current document object.
  +
  +=item * pod_pom_html_anchor
  +
  +  my $anchor = $self->pod_pom_html_anchor($title);
  +
  +this is common function that takes the C<$title> Pod::POM object,
  +converts it into a E<lt>a nameE<gt> html anchor and returns it.
  +
  +=item * pod_pom_html_view_verbatim
  +
  +this is an overloaded C<Pod::POM::HTML::view_verbatim()> method which
  +renders the E<lt>preE<gt>...E<lt>/preE<gt> html, but embeds a virtual
  +colored line as the left column, so the rendered text will stand out
  +from the normal text.
  +
  +=back
  +
  +
  +=head1 AUTHORS
  +
  +Stas Bekman E<lt>stas (at) stason.orgE<gt>
  +
  +=cut
  +
  
  
  
  1.4       +55 -3     modperl-docs/lib/DocSet/Doc/POD2HTML.pm
  
  Index: POD2HTML.pm
  ===================================================================
  RCS file: /home/cvs/modperl-docs/lib/DocSet/Doc/POD2HTML.pm,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- POD2HTML.pm       5 Feb 2002 10:27:19 -0000       1.3
  +++ POD2HTML.pm       22 Mar 2002 02:01:51 -0000      1.4
  @@ -4,12 +4,12 @@
   use warnings;
   
   use File::Spec::Functions;
  +use File::Basename ();
   
   use DocSet::Util;
  +use DocSet::RunTime;
   
   require Pod::POM;
  -#require Pod::POM::View::HTML;
  -#my $view_mode = 'Pod::POM::View::HTML';
   my $view_mode = 'DocSet::Doc::POD2HTML::View::HTML';
   
   use DocSet::Doc::Common ();
  @@ -25,6 +25,8 @@
   sub convert {
       my($self) = @_;
   
  +    set_render_obj($self);
  +
       my $pom = $self->{parsed_tree};
   
       my @sections = $pom->content();
  @@ -58,6 +60,8 @@
       my $tmpl_root = $self->{tmpl_root};
       $self->{output} = proc_tmpl($tmpl_root, $tmpl_file, $mode, {doc => 
$vars} );
   
  +    unset_render_obj();
  +
   }
   
   
  @@ -91,6 +95,11 @@
   require Pod::POM::View::HTML;
   @ISA = qw( Pod::POM::View::HTML);
   
  +use DocSet::RunTime;
  +
  +use File::Spec::Functions;
  +use File::Basename;
  +
   sub view_head1 {
       my ($self, $head1) = @_;
       return "<h1>" . $self->anchor($head1->title) . "</h1>\n\n" .
  @@ -115,9 +124,34 @@
           $head4->content->present($self);
   }
   
  +sub view_seq_file {
  +    my ($self, $path) = @_;
  +    my $doc_obj = get_render_obj();
  +    my $base_dir = dirname catfile $doc_obj->{src_root}, $doc_obj->{src_uri};
  +    my $file = catfile $base_dir, $path;
  +    #warn "file: $file";
  +
  +    # XXX: may need to test the location at dest_path, not src, to
  +    # make sure that the file actually gets copied
  +    return -e $file ? qq{<a href="$path">$path</a>} : qq{<i>$path</i>};
  +}
  +
   *anchor        = \&DocSet::Doc::Common::pod_pom_html_anchor;
  -*view_seq_link = \&DocSet::Doc::Common::pod_pom_html_view_seq_link;
   *view_verbatim = \&DocSet::Doc::Common::pod_pom_html_view_verbatim;
  +*view_seq_link_transform_path = 
\&DocSet::Doc::Common::pod_pom_html_view_seq_link_transform_path;
  +
  +#*view_seq_link = \&DocSet::Doc::Common::pod_pom_html_view_seq_link;
  +
  +#use DocSet::Util;
  +## META: temp override
  +## the one in superclass screws up URLs in L<>: L<http://foo.bar.com>
  +## should view_seq_text be called at all on these parts?
  +#sub view_seq_text {
  +#    my ($self, $text) = @_;
  +#dumper $self;
  +##print $self->[CMD];
  +#    return $text;
  +#}
   
   1;
   
  @@ -147,6 +181,24 @@
   =item * convert
   
   =back
  +
  +=head1 Rendering Class
  +
  +documents using this class are rendered via
  +C<DocSet::Doc::POD2HTML::View::HTML>, which is a subclass of
  +C<Pod::POM::View::HTML>.
  +
  +C<view_head{1-4}()> are overridden to add the E<lt>a nameE<gt> anchors
  +next to the headers for proper hyperlinking.
  +
  +view_seq_file() is overriden too. Here we search for the file relative
  +to the location of the document and if we find it we link to it
  +otherwise the default behaviour applies (the file path is turned into
  +italics).
  +
  +The following rendering methods: view_verbatim(), anchor() and
  +view_seq_link_transform_path() are defined in the
  +C<DocSet::Doc::Common> class and documented there.
   
   =head1 AUTHORS
   
  
  
  
  1.3       +61 -1     modperl-docs/lib/DocSet/Doc/POD2HTMLPS.pm
  
  Index: POD2HTMLPS.pm
  ===================================================================
  RCS file: /home/cvs/modperl-docs/lib/DocSet/Doc/POD2HTMLPS.pm,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- POD2HTMLPS.pm     5 Feb 2002 10:27:19 -0000       1.2
  +++ POD2HTMLPS.pm     22 Mar 2002 02:01:51 -0000      1.3
  @@ -4,6 +4,7 @@
   use warnings;
   
   use DocSet::Util;
  +use DocSet::RunTime;
   
   use vars qw(@ISA);
   require DocSet::Source::POD;
  @@ -22,6 +23,8 @@
   sub convert {
       my($self) = @_;
   
  +    set_render_obj($self);
  +
       my $pom = $self->{parsed_tree};
   
       my @sections = $pom->content();
  @@ -49,6 +52,8 @@
       my $tmpl_root = $self->{tmpl_root};
       $self->{output} = proc_tmpl($tmpl_root, $tmpl_file, $mode, {doc => 
$vars} );
   
  +    unset_render_obj();
  +
   }
   
   
  @@ -77,6 +82,12 @@
   
   package DocSet::Doc::POD2HTML::View::HTMLPS;
   
  +use DocSet::RunTime;
  +use DocSet::Util;
  +
  +use File::Spec::Functions;
  +use File::Basename;
  +
   use vars qw(@ISA);
   require Pod::POM::View::HTML;
   @ISA = qw( Pod::POM::View::HTML);
  @@ -108,9 +119,29 @@
           $head4->content->present($self);
   }
   
  +sub view_seq_file {
  +    my ($self, $path) = @_;
  +    my $doc_obj = get_render_obj();
  +    my $base_dir = dirname catfile $doc_obj->{src_root}, $doc_obj->{src_uri};
  +    my $file = catfile $base_dir, $path;
  +    #warn "file: $file";
  +
  +    return qq{<i>$path</i>} unless -e $file;
  +
  +    # since we cannot link to the text files which should stay as is
  +    # from ps/pdf, we simply include them inlined
  +    my $content = '';
  +    read_file($file, \$content);
  +
  +    return qq{<i>$path</i>:\n\n<pre>$content</pre>\n\n};
  +}
  +
  +
   *anchor        = \&DocSet::Doc::Common::pod_pom_html_anchor;
  -*view_seq_link = \&DocSet::Doc::Common::pod_pom_html_view_seq_link;
   *view_verbatim = \&DocSet::Doc::Common::pod_pom_html_view_verbatim;
  +*view_seq_link_transform_path = 
\&DocSet::Doc::Common::pod_pom_html_view_seq_link_transform_path;
  +
  +#*view_seq_link = \&DocSet::Doc::Common::pod_pom_html_view_seq_link;
   
   1;
   
  @@ -140,6 +171,35 @@
   =item * convert
   
   =back
  +
  +=head1 Rendering Class
  +
  +documents using this class are rendered via
  +C<DocSet::Doc::POD2HTML::View::HTMLPS>, which is a subclass of
  +C<Pod::POM::View::HTML>.
  +
  +Since we want the final PDF document which potentially includes many
  +chapters in it to look more as a book and have a nice Table of
  +Contents, we need to change the default structure of C<=head1> specs,
  +so the C<=head1 NAME> becomes a title of the chapter and removed from
  +the POD source, therefore we need to bump up all the remaining
  +C<=headX> headers by one. i.e. C<=head1> is rendered as C<=head2>,
  +C<=head3> as C<=head3>, etc. Therefore we override the super class's
  +methods C<view_head{1-4}>. In addition we put E<lt>a nameE<gt> anchors
  +next to the headers so the PDF document can be hyperlinked if the
  +reader supports this feature.
  +
  +view_seq_file() is overriden too. Here we search for the file relative
  +to the location of the document and if we find it we include its
  +contents since the PDFs are created for making dead tree copies and
  +therefore linking is not an option. Notice that it's OK to say
  +FE<lt>/etc/passwdE<gt> since it won't be found unless you actually put
  +it under the current documents path or put the source document in
  +the I</> path.
  +
  +The following rendering methods: view_verbatim(), anchor() and
  +view_seq_link_transform_path() are defined in the
  +C<DocSet::Doc::Common> class and documented there.
   
   =head1 AUTHORS
   
  
  
  
  1.3       +3 -2      modperl-docs/lib/DocSet/DocSet/HTML.pm
  
  Index: HTML.pm
  ===================================================================
  RCS file: /home/cvs/modperl-docs/lib/DocSet/DocSet/HTML.pm,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- HTML.pm   24 Jan 2002 18:11:24 -0000      1.2
  +++ HTML.pm   22 Mar 2002 02:01:52 -0000      1.3
  @@ -77,8 +77,9 @@
       }
   
       my $dir = {
  -        abs_doc_root => $self->get_dir('abs_doc_root'),
  -        rel_doc_root => $self->get_dir('rel_parent_root'),
  +        abs_doc_root   => $self->get_dir('abs_doc_root'),
  +        rel_doc_root   => $self->get_dir('rel_parent_root'),
  +        path_from_base => $self->get_dir('path_from_base'),
       };
   
       my $meta = {
  
  
  
  1.3       +4 -3      modperl-docs/lib/DocSet/DocSet/PSPDF.pm
  
  Index: PSPDF.pm
  ===================================================================
  RCS file: /home/cvs/modperl-docs/lib/DocSet/DocSet/PSPDF.pm,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- PSPDF.pm  24 Jan 2002 18:11:24 -0000      1.2
  +++ PSPDF.pm  22 Mar 2002 02:01:52 -0000      1.3
  @@ -55,9 +55,10 @@
       my($self) = @_;
   
       my $dir = {
  -               abs_doc_root => $self->get_dir('abs_doc_root'),
  -               rel_doc_root => '..', # META: probably wrong! (see 
write_index_html_file())
  -              };
  +        abs_doc_root => $self->get_dir('abs_doc_root'),
  +        rel_doc_root => '..', # META: probably wrong, could be ../..! (see 
write_index_html_file())
  +        path_from_base => $self->get_dir('path_from_base'),
  +    };
   
       my $meta = {
                   title    => $self->get('title'),
  
  
  
  1.4       +37 -0     modperl-docs/lib/DocSet/Source/POD.pm
  
  Index: POD.pm
  ===================================================================
  RCS file: /home/cvs/modperl-docs/lib/DocSet/Source/POD.pm,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- POD.pm    5 Feb 2002 10:27:20 -0000       1.3
  +++ POD.pm    22 Mar 2002 02:01:52 -0000      1.4
  @@ -230,6 +230,43 @@
   
   =head1 DESCRIPTION
   
  +META: not sure if the customized implementation of L<> belongs
  +here. But it works as follows:
  +
  +Assuming that the main I<config.cfg> specifies the following argument:
  +
  +     dir => {
  +             ...
  +  
  +             # search path for pods, etc. must put more specific paths first!
  +             search_paths => [qw(
  +                 docs/2.0/api/mod_perl-2.0 
  +                 docs/2.0/api/ModPerl-Registry 
  +                 docs/2.0 
  +                 docs/1.0
  +                 .
  +             )],
  +  
  +             # what extensions to search for
  +             search_exts => [qw(pod pm html)],
  +  
  +         },  
  +
  +Whenever the pod includes L<Title|foo::bar/section>, the code will
  +first convert C<foo::bar> into I<foo/bar> and then will try to find
  +the file I<foo/bar.pod> in the search path (similar to C<@INC>), as
  +well as files I<foo/bar.pm> and I<foo/bar.html> under dir I<src>. If
  +other C<search_exts> are specified they will be searched as well. If
  +there is a much the link will be created, otherwise only the title of
  +the link will be displayed.
  +
  +Notice that the C<search_paths> must specify more specific paths
  +first. If you don't they won't be searched. Currently this is done
  +only to optimize memory usage and some speed, not sure if that's very
  +important. But this is different from how Perl does search with
  +C<@INC> since DocSet reads all the files in memory once and then
  +reuses this data.
  +
   =head2 METHODS
   
   =over 
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to