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]