Changeset 13829


Ignore:
Timestamp:
01/26/12 03:43:38 (4 weeks ago)
Author:
KipLubliner
Message:

Item11437: merge Add package navigation to Perl Doc

Location:
branches/Release01x01/core
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • branches/Release01x01/core/data/System/PerlDoc.txt

    r12748 r13829  
    11%META:TOPICINFO{author="ProjectContributor" date="1303184283" format="1.1" version="1"}% 
    22%META:TOPICPARENT{name="DeveloperDocumentationCategory"}% 
    3 ---+!! %TOPIC% 
    4 <form class='foswikiForm'> 
     3%DOC_TITLE% 
     4<form class='foswikiForm' action='%SCRIPTURL{view}%/%SYSTEMWEB%/PerlDoc'> 
    55<div class='foswikiFormSteps'> 
    66  <div class='foswikiFormStep'> 
    77    <label for='module'><b>Perl Module:</b></label> 
    8     <input type='text' name='module' id='module' value='%URLPARAM{module}%' class='foswikiInputField foswikiFocus' /> 
     8    <input type='text' name='module' id='module' value='%URLPARAM{module}%' class='foswikiInputField' /> 
     9    <label for='publicOnly'><b>Public Only:</b></label> 
     10    <input type='checkbox' name='publicOnly' id='publicOnly' value='on' %IF{"$publicOnly = 'on'" then="checked='checked'"}% class='foswikiInputField' /> 
    911    <input type='submit' value='%MAKETEXT{"Submit"}%' class='foswikiSubmit' /> 
    1012    <div class="foswikiFormDescription"> 
    11       Enter a module name that to extract the perl documentation, e.g. <a href="%SCRIPTURLPATH{"view"}%/%WEB%/%TOPIC%?module=Foswiki::Func">Foswiki::Func</a> or, <a href="%SCRIPTURLPATH{"view"}%/%WEB%/%TOPIC%?module=Foswiki::Meta">Foswiki::Meta</a>. 
     13      Enter a module name that to extract the perl documentation, e.g. <a href="%SCRIPTURLPATH{"view"}%/%WEB%/%TOPIC%?module=Foswiki::Func%IF{"$publicOnly = 'on'" then=";publicOnly=on"}%">Foswiki::Func</a> or, <a href="%SCRIPTURLPATH{"view"}%/%WEB%/%TOPIC%?module=Foswiki::Meta%IF{"$publicOnly = 'on'" then=";publicOnly=on"}%">Foswiki::Meta</a>.<br/> 
     14      See also [[DevelopingPlugins][Developing plugins]], [[Foswiki:Development.DevelopersBible][Developer's Bible]], [[Foswiki:Development.TechnicalOverview][Technical Overview]]  
    1215    </div> 
     16  </div> 
     17  <div class='foswikiFormStep'> 
     18    %TWISTY{link="Child packages" linkclass="foswikiButton" remember="on"}% 
     19 
     20%DOC_CHILDREN% 
     21    %ENDTWISTY% 
    1322  </div> 
    1423</div> 
    1524</form> 
    16  
    17 Check [[DevelopingPlugins][Developing plugins]] and [[Foswiki:Development.DevelopersBible][Developer's Bible]] for more information. 
    1825 
    1926%SMELLS% 
     
    2128%TOC% 
    2229 
    23 %INCLUDE{"doc:%URLPARAM{module}%" level="2"}% 
     30%STARTSECTION{"doc"}% 
     31%INCLUDE{"doc:%URLPARAM{module}%" publicOnly="%URLPARAM{publicOnly}%" level="2"}% 
     32%ENDSECTION{"doc"}% 
  • branches/Release01x01/core/lib/Foswiki/IncludeHandlers/doc.pm

    r13288 r13829  
    33=begin TML 
    44 
    5 ---+ =package= Foswiki::IncludeHandlers::doc 
     5---+ package Foswiki::IncludeHandlers::doc 
    66 
    77This package is designed to be lazy-loaded when Foswiki sees 
     
    1818use Foswiki (); 
    1919 
     20use constant PUBLISHED_API_TOPIC => 'PublishedAPI'; 
     21 
    2022# Include embedded doc in a core module 
    2123sub INCLUDE { 
    2224    my ( $ignore, $session, $control, $params ) = @_; 
    23     my $class = $control->{_DEFAULT}; 
     25    my %removedblocks = (); 
     26    my $class         = $control->{_DEFAULT} || 'doc:Foswiki'; 
     27    my $publicOnly = ($params->{publicOnly} || '') eq 'on'; 
    2428    Foswiki::Func::setPreferencesValue( 'SMELLS', '' ); 
     29    # SMELL This is no longer being used in PerlDoc ...  
     30#    Foswiki::Func::setPreferencesValue( 'DOC_PARENT', '' ); 
     31    Foswiki::Func::setPreferencesValue( 'DOC_CHILDREN', '' ); 
     32    Foswiki::Func::setPreferencesValue( 'DOC_TITLE', '---++ !! !%TOPIC%' ); 
    2533    $class =~ s/[a-z]+://;    # remove protocol 
    26     return '' unless $class && $class =~ /^Foswiki/; 
     34    $class ||= 'Foswiki';     # provide a reasonable default 
     35#    return '' unless $class && $class =~ /^Foswiki/; 
    2736    $class =~ s/[^\w:]//g; 
     37 
     38    my %publicPackages = map {$_ => 1} _loadPublishedAPI(); 
     39    my $visibility = exists $publicPackages{$class} ? 'public' : 'internal'; 
     40    _setNavigation($class, $publicOnly, \%publicPackages); 
     41    Foswiki::Func::setPreferencesValue( 'DOC_TITLE', "---++ !! =$visibility package= " . _renderTitle($class) ); 
    2842 
    2943    my $pmfile; 
     
    4357    my $howSmelly  = 0; 
    4458    my $showSmells = !Foswiki::Func::isGuest(); 
    45     local $/ = "\n"; 
    46     while ( my $line = <$PMFILE> ) { 
     59    local $/ = undef; 
     60    my $perl = <$PMFILE>; 
     61    my $isa; 
     62    my $inSuppressedMethod; 
     63 
     64    if ( $perl =~ /our\s+\@ISA\s*=\s*\(\s*['"](.*?)['"]\s*\)/ ) { 
     65        $isa = " ==is a== $1"; 
     66        $isa =~ s#\s(Foswiki(?:::[A-Z]\w+)+)#' ' . _doclink($1)#ge; 
     67    } 
     68    $perl = Foswiki::takeOutBlocks( $perl, 'verbatim', \%removedblocks ); 
     69    foreach my $line ( split( /\r?\n/, $perl ) ) { 
    4770        if ( $line =~ /^=(begin (twiki|TML|html)|pod)/ ) { 
    4871            $inPod = 1; 
     72            $inSuppressedMethod = 0; 
    4973        } 
    5074        elsif ( $line =~ /^=cut/ ) { 
     
    5276        } 
    5377        elsif ($inPod) { 
    54             $pod .= $line; 
    55         } 
    56         if ( $line =~ /(SMELL|FIXME|TODO)/ && $showSmells ) { 
     78            if ( $line =~ /^---\+(!!)?\s+package\s+\S+\s*$/ ) { 
     79                if ($isa) { 
     80                    $line .= $isa; 
     81                    $isa = undef; 
     82                } 
     83                $line =~ s/^---\+(?:!!)?\s+package\s*(.*)/---+ =$visibility package= $1/; 
     84            } 
     85            else { 
     86                $line =~ s#\b(Foswiki(?:::[A-Z]\w+)+)#_doclink($1)#geo; 
     87            } 
     88            if ( $line =~ s/^(---\++\s+)(\w+Method)\s+/$1=$2= / ) { 
     89                $line =~ s/\s+[-=]>\s+/ &rarr; /; 
     90                if ($publicOnly && $line =~ /Method=\s+_/) { 
     91                    $inSuppressedMethod = 1; 
     92                } 
     93            } elsif ($line =~ /^---/) { 
     94                $inSuppressedMethod = 0; 
     95            } 
     96            $pod .= "$line\n" 
     97                unless $inSuppressedMethod; 
     98        } 
     99        if (!$inSuppressedMethod && $line =~ /(SMELL|FIXME|TODO)/ && $showSmells ) { 
    57100            $howSmelly++; 
    58101            $pod .= "<blockquote class=\"foswikiAlert\">$line</blockquote>"; 
     
    60103    } 
    61104    close($PMFILE); 
     105    Foswiki::putBackBlocks( \$pod, \%removedblocks, 'verbatim', 'verbatim' ); 
    62106 
    63107    $pod =~ s/.*?%STARTINCLUDE%//s; 
     
    88132} 
    89133 
     134# set DOC_CHILDREN preference value to a list of sub-packages. 
     135sub _setNavigation { 
     136    my ($class, $publicOnly, $publicPackages) = @_; 
     137    my @children; 
     138    my %childrenDesc; 
     139    my $classPrefix = $class . '::'; 
     140#    my $classParent = $class; 
     141#    $classParent =~ s/::[^:]+$//; 
     142#    Foswiki::Func::setPreferencesValue( 'DOC_PARENT', _doclink($classParent) ); 
     143    $class =~ s#::#/#g; 
     144 
     145    foreach my $inc (@INC) { 
     146        if ( -d "$inc/$class" and opendir my $dh, "$inc/$class") { 
     147            my @dir = grep { !/^\./ } readdir($dh); 
     148            push @children, map { -d "$inc/$class/$_" ? "$classPrefix$_" : () } @dir; 
     149            for my $d (@dir) { 
     150                if ($d =~ s/\.pm$//) { 
     151                    push @children, "$classPrefix$d"; 
     152                    $childrenDesc{"$classPrefix$d"} = _getPackSummary("$inc/$class/$d.pm"); 
     153                }                
     154            } 
     155            closedir $dh; 
     156        } 
     157    } 
     158    if ($publicOnly) { 
     159        @children = grep { exists $publicPackages->{$_} } @children; 
     160    } 
     161    my $children = '<ul>'; 
     162    if (@children) { 
     163        my %children = map { $_ => 1 } @children; 
     164        @children = sort keys %children; 
     165        foreach my $child (@children) { 
     166            my $desc = $childrenDesc{$child} ? ' - ' . $childrenDesc{$child} : ''; 
     167            $children .= '<li>' . _doclink($child) . "$desc</li>\n"; 
     168        } 
     169    } 
     170    $children .= '</ul>'; 
     171    Foswiki::Func::setPreferencesValue( 'DOC_CHILDREN', $children ); 
     172} 
     173 
     174# get a summary of the pod documentation by looking directly after the ---+ package TML. 
     175sub _getPackSummary ($) { 
     176    my $pmfile = $_[0]; 
     177    my @summary; 
     178 
     179    my $PMFILE; 
     180    open( $PMFILE, '<', $pmfile ) || return ''; 
     181    my $inPod      = 0; 
     182    my $inPackage  = 0; 
     183    while (my $line = <$PMFILE>) { 
     184        if ( $line =~ /^=(begin (twiki|TML|html)|pod)/ ) { 
     185            $inPod = 1; 
     186        } 
     187        elsif ( $line =~ /^=cut/ ) { 
     188            @summary 
     189                and last; 
     190            $inPod = 0; 
     191        } 
     192        elsif ($inPod) { 
     193            if ($inPackage) { 
     194                chomp($line); 
     195                push @summary, $line; 
     196            } 
     197            if ( $line =~ /^---\+(!!)?\s+package\s+\S+\s*$/ ) { 
     198                $inPackage = 1; 
     199            } 
     200        } 
     201    } 
     202    close($PMFILE); 
     203 
     204    while (@summary) { 
     205        if ($summary[0] =~ /^\s*$/) { 
     206            shift @summary; 
     207        } else { 
     208            last; 
     209        } 
     210    } 
     211    if (!@summary) { 
     212        return ''; 
     213    } 
     214    my $emptyLine = 0; 
     215    while ($emptyLine < @summary && $summary[$emptyLine] !~ /^\s*$/) { 
     216        $emptyLine++; 
     217    } 
     218    return join ' ', @summary[0 .. $emptyLine - 1]; 
     219} 
     220 
     221sub _loadPublishedAPI { 
     222    my ($meta, $text) = Foswiki::Func::readTopic($Foswiki::cfg{SystemWebName}, PUBLISHED_API_TOPIC); 
     223    my @ret; 
     224    for my $line (split /\r?\n/, $text) { 
     225        $line =~ /^\|\s*package\s*\|\s*(.*?)\s*\|/ 
     226            and push @ret, $1; 
     227    } 
     228    return @ret; 
     229} 
     230 
     231# Make each intermediate package into a doc link. 
     232sub _renderTitle { 
     233    my $pack = $_[0]; 
     234    my @packComps = split '::', $pack; 
     235    my @packLinks = map { _doclink((join '::', @packComps[0 .. $_]), $packComps[$_]) } 0 .. $#packComps - 1; 
     236    my $packageTitle = join '::', @packLinks, $packComps[$#packComps]; 
     237    return $packageTitle; 
     238} 
     239 
     240sub _doclink ($) { 
     241    my $module = $_[0]; 
     242    my $title = $_[1] || $module; 
     243    # SMELL relying on TML to set publicOnly 
     244    return "[[%SCRIPTURL{view}%/%SYSTEMWEB%/PerlDoc?module=$module%IF{\"\$publicOnly = 'on'\" then=\";publicOnly=on\"}%][$title]]"; 
     245} 
     246 
    902471; 
    91248 
     
    93250Foswiki - The Free and Open Source Wiki, http://foswiki.org/ 
    94251 
    95 Copyright (C) 2008-2010 Foswiki Contributors. Foswiki Contributors 
     252Copyright (C) 2008-2012 Foswiki Contributors. Foswiki Contributors 
    96253are listed in the AUTHORS file in the root of this distribution. 
    97254NOTE: Please extend that file, not this notice. 
Note: See TracChangeset for help on using the changeset viewer.