#!/usr/bin/perl #============================================================================ # # File : gendoc.pl # Creation date : Sun 17 Dec 2006 20:36:07 by Szymon Stefanek # # This file is part of the KVIrc IRC Client distribution # Copyright (C) 2000-2009 Szymon Stefanek # # This program is FREE software. You can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the HOPE that it will be USEFUL, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # #============================================================================ ################################################################################################# # GLOBAL CONFIGS ################################################################################################# $g_currenttime = gmtime($ENV{SOURCE_DATE_EPOCH} || time); $g_currentuser = $ENV{USER} || getlogin || getpwuid($<) || "Unknown"; $g_syntaxcolor="#802000"; $g_kvssyntaxcolor="#802000"; $g_kvstypenamecolor="#808080"; $g_kvstypedelimiterscolor="#8080a0"; $g_bodybgcolor="#FFFFFF"; $g_bodytextcolor="#000000"; $g_bodylinkcolor="#000000"; $g_tablebgcolor="#F4F4F4"; $g_internaltablecolor="#D5D5D5"; $g_classfnctablecolor="#D5D5D5"; $g_classfncbodytablecolor="#EDEDED"; $g_bodytablebgcolor="#EAEAEA"; $g_commentcolor="#207500"; $g_fileextension=".html"; #$g_headerborderlightcolor="#A0A0A0"; #$g_headerborderdarkcolor="#000000"; $g_headerbgcolor="#FFFFFF"; $g_prefixes{'command'}="cmd"; $g_prefixes{'function'}="fnc"; $g_prefixes{'event'}="event"; $g_prefixes{'language'}="doc"; $g_prefixes{'class'}="class"; $g_prefixes{'module'}="module"; $g_prefixes{'widget'}="widget"; $g_version = "4.0.0"; $g_filehandle=""; $g_shortsIdx{"keyterms"}=0; $g_directory = ""; $g_css = ""; ################################################################################################# # PARSE ARGS ################################################################################################# sub usage { print "\n"; print "Usage:\n"; print " gendoc.pl [-v ] ...\n"; print "Parameters:\n"; print " : directory where the doc files should be written\n"; print " ... : a list of directories from which to extract docs\n"; print "Options:\n"; print " -v forces the specified version to be displayed in the\n"; print " generated documents\n"; print "Notes:\n"; print " Docs will be extracted only by files with these extensions:\n"; print " .h .cpp .template\n"; print "\n"; } $i = 0; $cont = 1; while($cont) { if($ARGV[$i] eq "--version") { print "gendoc.pl 2.0.0: KVIrc documentation generator\n"; exit(0); } elsif($ARGV[$i] eq "-v") { $i++; if($ARGV[$i] eq "") { usage(); die "Switch -v requires a parameter" } $g_version = $ARGV[$i]; $i++; } elsif($ARGV[$i] eq "--css") { $i++; if($ARGV[$i] eq "") { usage(); die "Switch --css requires a parameter" } $g_css = $ARGV[$i]; $i++; } else { $cont = 0; # stop processing } } $g_directory = $ARGV[$i]; $i++; if($g_directory eq "") { usage(); die "Missing target directory"; } $j = 0; while($ARGV[$i] ne "") { recurse($ARGV[$i]); $i++; } ################################################################################################# # SUBS ################################################################################################# sub recurse($) { my($path) = @_; ## append a trailing / if it's not there $path .= '/' if($path !~ /\/$/); ## loop through the files contained in the directory for my $eachFile (glob($path.'*')) { ## if the file is a directory if( -d $eachFile) { ## pass the directory to the routine ( recursion ) recurse($eachFile); } else { if($eachFile =~ /(\.cpp|\.h|\.template)$/) { $g_filesToProcess[$j] = $eachFile; $j++; } } } } sub print_header { print $g_filehandle "\n"; print $g_filehandle "\n"; print $g_filehandle "\n"; print $g_filehandle "$_[0]\n"; print $g_filehandle "\n"; print $g_filehandle "\n"; print $g_filehandle "\n"; print $g_filehandle "\n"; print $g_filehandle " \n"; print $g_filehandle " \n"; print $g_filehandle " \n"; print $g_filehandle " \n"; print $g_filehandle "
\n"; print $g_filehandle " \n"; print $g_filehandle " \n"; print $g_filehandle " \n"; print $g_filehandle "
\n"; } sub print_footer { print $g_filehandle "\n"; print $g_filehandle "\n"; print $g_filehandle "\n"; } sub print_tablestart { print $g_filehandle "\n"; #print $g_filehandle "\n"; print $g_filehandle "
\n"; } sub print_tableend { #print $g_filehandle "
\n"; } sub print_title { print $g_filehandle " \n"; print $g_filehandle " \n"; print $g_filehandle "
$_[0]
"; if($_[1] ne "") { print $g_filehandle "
$_[1]
"; } print $g_filehandle " \n"; print $g_filehandle " \n"; } sub print_twocolumntitle { print $g_filehandle " \n"; print $g_filehandle " \n"; print $g_filehandle "
$_[0]
"; if($_[1] ne "") { print $g_filehandle "
$_[1]
"; } print $g_filehandle " \n"; print $g_filehandle " \n"; } sub print_subtitle { print $g_filehandle " \n"; print $g_filehandle "
$_[0]
\n"; print $g_filehandle " \n"; } sub print_twocolumnsubtitle { print $g_filehandle " \n"; print $g_filehandle "
$_[0]
\n"; print $g_filehandle " \n"; } sub print_body { print $g_filehandle " \n"; print $g_filehandle " $_[0]\n"; print $g_filehandle " \n"; } sub print_twocolumnbody { print $g_filehandle "\n"; print $g_filehandle " $_[0]\n"; print $g_filehandle " $_[1]\n"; print $g_filehandle "\n"; } sub print_entry { if($_[1] ne "") { if($_[0] ne "") { print_subtitle($_[0]); } print_body($_[1]); } } sub make_single_token { $_[0] =~ s/^[ ]*//g; $_[0] =~ s/[ ]*$//g; $_[0] =~ s/\n//g; } sub make_single_line { $_[0] =~ s/^[ \n]*//g; $_[0] =~ s/[ \n]*$//gs; } sub make_syntax { $_[0] =~ s/^[ \n]*//g; $_[0] =~ s/[ \n]*$//gs; my @arry; @arry = split('\n',$_[0]); $_[0] = ""; foreach(@arry) { $_ =~ s/^[ \n]*//g; if($_ ne "") { if($_[0] ne "") { $_[0] = "$_[0]\n$_"; } else { $_[0] = "$_"; } } } $_[0] =~ s/\n+/
\n/gs; } sub extract_keyterms { my($docfilename); my(%parts); my($part); # Part title my($partbody); my($tabblock); my($tmp); my($type); if(!open(CPPFILE,"$_[0]")) { return; } # Process the entire file while() { if(/^[ ]*\@doc:[ a-z_]*/) { # Process a single document block $docfilename="$_"; $docfilename=~ s/[ ]*//g; $docfilename=~ s/\@doc://g; $docfilename=~ s/\n//g; $docfilename=~ s/\r//g; $docfilename=~ s/([a-zA-Z_]*)/\L\1/g; undef %parts; $part = ""; INNERLOOP: while() { if(/^[ ]*\*\/[ ]*/) { # End of comment if(($part ne "") && ($partbody ne "") && ($partbody ne "\n")) { # We have an entire part to store $parts{$part}="$partbody"; } last INNERLOOP; } else { # Inside a part if(/^[ ]*\@[a-z]*:[ ]*/) { # A part title if(($part ne "") && ($partbody ne "") && ($partbody ne "\n")) { # We have an entire part to store $parts{$part}="$partbody"; } # Start of the part # Extract the title $part="$_"; $part=~ s/[ ]*//g; $part=~ s/\@//g; $part=~ s/://g; $part=~ s/\n//g; # Clear the body (begin) $partbody=""; } else { # Somewhere in a part body if(($_ ne "") && ($_ ne "\n")) { if($partbody eq "") { # If it is the first line of the part body # Extract the amount of tabs that the part has # We will use it to remove the C++ indentation $tabblock = "$_"; $tabblock =~ s/^([ ]*).*/\1/g; $tabblock =~ s/\n//g; } if($tabblock ne "") { # If we have the initial tabblock , remove it from the line (remove indentation) $_ =~ s/^$tabblock//g; } process_body_line($_,0); $partbody="$partbody$_"; } } } } # OK... We have a document in $parts make_single_line($parts{'short'}); make_single_token($parts{'title'}); make_single_token($parts{'type'}); $parts{'type'}=~ s/\@//g; $parts{'type'}=~ s/://g; if($parts{'type'} eq "") { $parts{'type'}="generic"; } $type = $parts{'type'}; $tmp = $g_prefixes{$type}; if($tmp eq "") { $tmp="doc"; } $docfilename="$tmp\_$docfilename"; $zzz="keyterms"; if($parts{'keyterms'} ne "") { $keyterms = $parts{'keyterms'}; $keyterms =~ s/\n//gs; for $term (split(/,/,$keyterms)) { make_single_token($term); if($term ne "") { $termx=$term; $termx=~ s/([\+\(\)\?\.\:\*\|\=\;\^\!\~])/\\$1/g; $g_keyterms{$term} = "$docfilename$g_fileextension"; $g_keytermsclean{$term} = "$termx"; $tmp="keyterms_$g_shortsIdx{$zzz}"; $g_shorts{$tmp}="$term$parts{'short'}$docfilename$g_fileextension"; #print "GOT $g_shorts{$tmp} ($tmp)"; $g_shortsIdx{$zzz}++; } } } $tmp="keyterms_$g_shortsIdx{$zzz}"; $g_shorts{$tmp}="$parts{'title'}$parts{'short'}$docfilename$g_fileextension"; #print "GOT $g_shorts{$tmp} ($tmp)"; $g_shortsIdx{$zzz}++; } } close(CPPFILE); } sub substitute_keyterms { my(@lines); my(@tmp); my($left); my($right); my($line); my($term); # Kinda complex keyword substitution routine # For each keyterm we have for $term (@g_keytermsSorted) { # If the doc we're scanning isn't the keyword target if($_[1] ne $g_keyterms{$term}) { $termclean=$g_keytermsclean{$term}; # If the doc matches the keyterm at least once if($_[0] =~ /$termclean/) { $ref=$g_keyterms{$term}; $ref =~ s/([a-zA-Z_]*)/\L\1/g; @tmp = split(//) { $skipIt=0 if /^[ ]*\/a[ ]*>/; } } if($skipIt) { $_[0]="$_[0]<$_"; } else { if(/[A-Za-z0-9\"]>/) { if(/^[ ]*a[ ][ ]*h/) { $skipIt=1; $first ? $_[0] .= $_ : $_[0] .= "<$_"; } else { ($left,$right) = split(/>/,$_); $right=~s/([^A-Za-z0-9<>\+\-\=_])($termclean)([^A-Za-z0-9<>\+\-\=_])/$1$2<\/a>$3/ig; $_[0] .= "<$left>$right"; } } else { $_=~s/([^A-Za-z0-9<>\+\-\=_\.])($termclean)([^A-Za-z0-9<>\+\-\=_\.])/$1$2<\/a>$3/ig; $_[0] .= $_; } $first=0; } } } } } } sub build_usage_from_kvs_syntax_line { $_[0] =~ s/\<\;([A-Za-z0-9_]+):([A-Za-z0-9_]+)\>\;/\<\;\1\>\;/g; $_[0] =~ s/\[([A-Za-z0-9_]+):([A-Za-z0-9_]+)\]/\[;\1\]/g; $_[0] =~ s/^\<\;([A-Za-z0-9_]+)\>\;//g; } sub build_usage_from_kvs_syntax { my @arry; @arry = split('\n',$_[0]); $tmp = ""; foreach(@arry) { build_usage_from_kvs_syntax_line($_); if($tmp ne "") { $tmp = "$tmp\n$_"; } else { $tmp = "$_"; } } return $tmp; } sub process_kvs_syntax_line { $_[0] =~ s/\<\;([A-Za-z0-9_]+):([A-Za-z0-9_]+)\>\;/\<\;\1\:\2\<\/font\>\>\;/g; $_[0] =~ s/\[([A-Za-z0-9_]+):([A-Za-z0-9_]+)\]/\[\1\:\2\<\/font\>\]/g; $_[0] =~ s/^\<\;([A-Za-z0-9_]+)\>\;/\<\;\\1\<\/font\>\>\;/g; $_[0] =~ s/^([A-Za-z0-9_\.]+)/\\1\<\/b\>/g; $_[0] =~ s/(\$[A-Za-z0-9_\.]*)/\\1\<\/b\>/g; $_[0] =~ s/\(/\\(<\/b\>/g; $_[0] =~ s/\)/\\)<\/b\>/g; $_[0] =~ s/\<\;/\\<\;\<\/font\>/g; $_[0] =~ s/\>\;/\\>\;\<\/font\>/g; $_[0] =~ s/\[/\\[\<\/font\>/g; $_[0] =~ s/\]/\\]\<\/font\>/g; } sub process_kvs_syntax { my @arry; @arry = split('\n',$_[0]); $_[0] = ""; foreach(@arry) { process_kvs_syntax_line($_); if($_[0] ne "") { $_[0] = "$_[0]\n$_"; } else { $_[0] = "$_"; } } } sub process_body_line { my($bInExample); $bInExample = $_[1]; # Kill plain text tags $_[0] =~ s/\/\>\;/g; if($bInExample) { # Additional processing for examples if($_[0] =~ /^[ ]*#.*/) { $_[0] =~ s/^(.*)(#[^\"]*)/\1\\2\<\/span\>/g; } else { $_[0] =~ s/([\(\)]+)/\\1\<\/span\>/g; $_[0] =~ s/([\{\}]+)/\\1\<\/span\>/g; $_[0] =~ s/(%[a-zA-Z0-9_\.]+)/\\1\<\/span\>/g; # Too hard to fix these #$_[0] =~ s/([ ][\.\+\-\*\=]+[ ]*)/\\1\<\/span\>/g; #$_[0] =~ s/(\>\;)/\\1\<\/span\>/g; #$_[0] =~ s/(\<\;)/\\1\<\/span\>/g; } $_[0] =~ s/\n+/
\n/gs; } $_[0] =~ s/^ /\ \;\ \;\ \;\ \;\ \;\ \;\ \;\ \;\ \;\ \;\ \;\ \;\ \;\ \;\ \;\ \;/g; $_[0] =~ s/^ /\ \;\ \;\ \;\ \;\ \;\ \;\ \;\ \;\ \;\ \;\ \;\ \;/g; $_[0] =~ s/^ /\ \;\ \;\ \;\ \;\ \;\ \;\ \;\ \;/g; $_[0] =~ s/^ /\ \;\ \;\ \;\ \;/g; $_[0] =~ s/\[br\]/\/g; $_[0] =~ s/\[b\]/\/g; $_[0] =~ s/\[p\]/\/g; $_[0] =~ s/\[\/p\]/\<\/p\>/g; $_[0] =~ s/\[\/b\]/\<\/b\>/g; # [big][/big] is an alias to [title][/title] $_[0] =~ s/\[big\]/\<\/td\>\<\/tr\>\\\
/g; $_[0] =~ s/\[\/big\]/\<\/div\>\<\/td\>\<\/tr\>\\/g; $_[0] =~ s/\[title\]/\<\/td\>\<\/tr\>\\\
/g; $_[0] =~ s/\[\/title\]/\<\/div\>\<\/td\>\<\/tr\>\\/g; $_[0] =~ s/\[subtitle\]/\<\/td\>\<\/tr\>\\\
/g; $_[0] =~ s/\[\/subtitle\]/\<\/div\>\<\/td\>\<\/tr\>\\/g; $_[0] =~ s/\[pre\]/\/g; $_[0] =~ s/\[\/pre\]/\<\/pre\>/g; $_[0] =~ s/\[center\]/\/g; $_[0] =~ s/\[\/center\]/\<\/center\>/g; $_[0] =~ s/\[i\]/\/g; $_[0] =~ s/\[\/i\]/\<\/i\>/g; $_[0] =~ s/\[ul\]/\/g; $_[0] =~ s/\[\/ul\]/\<\/ul\>/g; $_[0] =~ s/\[li\]/\/g; $_[0] =~ s/\[\/li\]/\<\/li\>/g; $_[0] =~ s/\[table\]/\/g; $_[0] =~ s/\[\/table\]/\<\/table\>/g; $_[0] =~ s/\[tr\]/\/g; $_[0] =~ s/\[\/tr\]/\<\/tr\>/g; $_[0] =~ s/\[td\]/\/g; $_[0] =~ s/\[\/td\]/\<\/td\>/g; $_[0] =~ s/\[example\][ \n]*/\<\/td\>\<\/tr\>\\\n"; print DOCFILE " \n"; print DOCFILE " \n"; } if($parts{'functions'} ne "") { print_subtitle("Functions"); print DOCFILE " \n"; print DOCFILE " \n"; print DOCFILE " \n"; } if($parts{'signals'} ne "") { print_subtitle("Signals"); print DOCFILE " \n"; print DOCFILE " \n"; print DOCFILE " \n"; } print_entry("Examples","$parts{'examples'}"); print_entry("See also","$parts{'seealso'}"); print_tableend(); if($parts{'type'} eq "command") { print DOCFILE "
Index, Commands\n"; } elsif($parts{'type'} eq "function") { print DOCFILE "
Index, Functions\n"; } elsif($parts{'type'} eq "event") { print DOCFILE "
Index, Events\n"; } elsif($parts{'type'} eq "generic") { print DOCFILE "
Index, Miscellaneous\n"; } elsif($parts{'type'} eq "language") { print DOCFILE "
Index, Language Overview\n"; } elsif($parts{'type'} eq "class") { print DOCFILE "
Index, Object Classes\n"; } elsif($parts{'type'} eq "module") { print DOCFILE "
Index, Modules\n"; } elsif($parts{'type'} eq "widget") { print DOCFILE "
Index, Features\n"; } print_footer(DOCFILE); close(DOCFILE); } else { print "Can't open $g_directory/$docfilename$g_fileextension for writing\n"; } } } close(CPPFILE); } ################################################################################################# # COMMAND/FUNCTION.... INDEXES ################################################################################################# sub generate_indexes { my(@oldCommands); my(@commands); my(@sortedCommands); my(@chars); my($alllinks); my($upcase); my($count); my($doctitle); my($category); my($number); $doctitle = $_[0]; $category = $_[1]; $number = $_[2]; #print("Generating indexes for $doctitle $category $number\n"); ###################################################### # generate some helper stuff (alphabetic index links) @chars=("\$","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"); $i = 0; $alllinks="
/g; $_[0] =~ s/\[\/example\]/\<\/td\>\<\/tr\>\\/g; $_[0] =~ s/\[comment\]//g; $_[0] =~ s/\[\/comment\]/<\/span>/g; # The doc tag needs to include '$(*)' due to the expressioneval article $_[0] =~ s/\[doc\]([a-zA-Z0-9_\$*\(\)]*)\[\/doc\]/\\1\<\/a\>/g; $_[0] =~ s/\[doc:([a-zA-Z0-9_]*)\]([a-zA-Z0-9_\-\&\;\.\$*\(\) ]*)\[\/doc\]/\\2\<\/a\>/g; $_[0] =~ s/\[cmd\]([a-zA-Z0-9_\.]*)\[\/cmd\]/\\1\<\/a\>/g; $_[0] =~ s/\[cmd:([a-zA-Z0-9_\.]*)\]([a-zA-Z0-9_\-\&\;\. ]*)\[\/cmd\]/\\2\<\/a\>/g; $_[0] =~ s/\[fnc\]\$([a-zA-Z0-9_\.]*)\[\/fnc\]/\\$\1\<\/a\>/g; $_[0] =~ s/\[fnc\]\$([a-zA-Z0-9_\.]*)\(\)\[\/fnc\]/\\$\1()\<\/a\>/g; $_[0] =~ s/\[fnc\]([a-zA-Z0-9_\.]*)\[\/fnc\]/\\$\1\<\/a\>/g; $_[0] =~ s/\[fnc:\$([a-zA-Z0-9_\.]*)\]\$([\$a-zA-Z0-9_\-\&\;\. ]*)\[\/fnc\]/\\$\2\<\/a\>/g; $_[0] =~ s/\[event\]\$([a-zA-Z0-9_]*)\[\/event\]/\\$\1\<\/a\>/g; $_[0] =~ s/\[event:([a-zA-Z0-9_]*)\]([a-zA-Z0-9_]*)\[\/event\]/\\2\<\/a\>/g; $_[0] =~ s/\[class\]([a-zA-Z0-9_]*)\[\/class\]/\\1\<\/a\>/g; $_[0] =~ s/\[class:([a-zA-Z0-9_]*)\]([a-zA-Z0-9_ ]*)\[\/class\]/\\2\<\/a\>/g; $_[0] =~ s/\[module:([a-zA-Z0-9_]*)\]([a-zA-Z0-9_ ]*)\[\/module\]/\\2\<\/a\>/g; $_[0] =~ s/\[widget:([a-zA-Z0-9_]*)\]([a-zA-Z0-9_ ]*)\[\/widget\]/\\2\<\/a\>/g; $_[0] =~ s/\[classfnc:([a-zA-Z0-9_]*)\]\$([a-zA-Z0-9_]*)\[\/classfnc\]/\\$\2\<\/a\>/g; $_[0] =~ s/\[classfnc\]\$([a-zA-Z0-9_]*)\[\/classfnc\]/\\$\1\<\/a\>/g; $_[0] =~ s/\[classsignal:([a-zA-Z0-9_]*)\]([a-zA-Z0-9_]*)\[\/classsignal\]/\\2\<\/a\>/g; $_[0] =~ s/\[classsignal\]([a-zA-Z0-9_]*)\[\/classsignal\]/\\1\<\/a\>/g; $_[0] =~ s/\[anchorlink:([^\]]*)\]/\/g; $_[0] =~ s/\[\/anchorlink\]/\<\/a\>/g; $_[0] =~ s/\[anchor:([a-zA-Z0-9_]*)\]/\/g; $_[0] =~ s/\[\/anchor\]/\<\/a\>/g; $_[0] =~ s/\[note\][ \n]*/\<\/td\>\<\/tr\>\\/g; $_[0] =~ s/\[\/note\]/\<\/td\>\<\/tr\>\\/g; } sub process_file { my($docfilename); my(%parts); my($part); # Part title my($partbody); my($tabblock); my($tmp); my($type); my($iExampleState); my($szExampleTabBlock); if(!open(CPPFILE,"$_[0]")) { return; } # Process the entire file $iExampleState = 0; while() { if(/^[ ]*\@doc:[ a-z_]*/) { # Process a single document block $docfilename="$_"; $docfilename=~ s/[ ]*//g; $docfilename=~ s/\@doc://g; $docfilename=~ s/\n//g; $docfilename=~ s/([a-zA-Z_]*)/\L\1/g; undef %parts; $part = ""; INNERLOOP: while() { if(/^[ ]*\*\/[ ]*/) { # End of comment if(($part ne "") && ($partbody ne "") && ($partbody ne "\n")) { # We have an entire part to store $parts{$part}="$partbody"; } last INNERLOOP; } else { # Inside a part if(/^[ ]*\@[a-z]*:[ ]*/) { # A part title if(($part ne "") && ($partbody ne "") && ($partbody ne "\n")) { # We have an entire part to store $parts{$part}="$partbody"; } # Start of the part # Extract the title $part="$_"; $part=~ s/[ ]*//g; $part=~ s/\@//g; $part=~ s/://g; $part=~ s/\n//g; # Clear the body (begin) $partbody=""; $iExampleState = 0; } else { # Somewhere in a part body if(($_ ne "") && ($_ ne "\n")) { if($partbody eq "") { # If it is the first line of the part body # Extract the amount of tabs that the part has # We will use it to remove the C++ indentation $tabblock = "$_"; $tabblock =~ s/^([ ]*).*/\1/g; $tabblock =~ s/\n//g; } if($tabblock ne "") { # If we have the initial tabblock , remove it from the line (remove indentation) $_ =~ s/^$tabblock//g; } # Process example code blocks if($iExampleState eq 0) { if(($_ =~ /\[(example|pre)\]*/) && (!($_ =~ /\[\/(example|pre)\]*/))) { $iExampleState = 1; $szExampleTabBlock = ""; } } else { if($szExampleTabBlock ne "") { # If we have the initial tabblock , remove it from the line (remove indentation) $_ =~ s/^$szExampleTabBlock//g; } if(($_ =~ /\[\/(example|pre)\]*/)) { $iExampleState = 0; } else { if($iExampleState eq 1) { $iExampleState = 2; $szExampleTabBlock = "$_"; $szExampleTabBlock =~ s/^([ ]*).*/\1/g; $szExampleTabBlock =~ s/\n//g; if($szExampleTabBlock ne "") { # If we have the initial tabblock , remove it from the line (remove indentation) $_ =~ s/^$szExampleTabBlock//g; } } } } process_body_line($_,$iExampleState); $partbody="$partbody$_"; } } } } # OK... We have a document in $parts # Process the title if($parts{'title'} eq "") { print "\n ($_[0]) Warning: no title specified for $docfilename\n"; $parts{'title'}="No title specified"; } make_single_token($parts{'title'}); if($parts{'syntax'} ne "") { if($parts{'usage'} eq "") { $parts{'usage'} = build_usage_from_kvs_syntax($parts{'syntax'}) } } make_syntax($parts{'usage'}); make_syntax($parts{'syntax'}); make_single_line($parts{'parameters'}); make_single_line($parts{'inherits'}); make_single_token($parts{'short'}); make_single_token($parts{'window'}); make_single_token($parts{'type'}); $parts{'type'}=~ s/\@//g; $parts{'type'}=~ s/://g; if($parts{'type'} eq "") { $parts{'type'}="generic"; } $type = $parts{'type'}; $tmp = $g_prefixes{$type}; if($tmp eq "") { $tmp="doc"; } $docfilename="$tmp\_$docfilename"; if($g_shortsIdx{$type} eq "") { $g_shortsIdx{$type} = 0; } $tmp="$type\_$g_shortsIdx{$type}"; $g_shorts{$tmp}="$parts{'title'}$parts{'short'}$docfilename$g_fileextension"; #print "$tmp, $g_shorts{$tmp}\n"; $g_shortsIdx{$type}++; # Keyterms substitution is confusing. Better to rely on manual linking only. #if($parts{'body'} ne "") #{ # substitute_keyterms($parts{'body'},"$docfilename$g_fileextension"); #} #if($parts{'description'} ne "") #{ # substitute_keyterms($parts{'description'},"$docfilename$g_fileextension"); #} #if($parts{'switches'} ne "") #{ # substitute_keyterms($parts{'switches'},"$docfilename$g_fileextension"); #} use File::Path; mkpath("$g_directory"); if(open(DOCFILE,">$g_directory/$docfilename$g_fileextension")) { $g_filehandle=DOCFILE; print_header($parts{'title'}); print_tablestart(); print_title($parts{'title'},$parts{'short'}); if($parts{'syntax'} ne "") { process_kvs_syntax($parts{'syntax'}); print_entry("Usage","
$parts{'syntax'}
"); } else { if($parts{'usage'} ne "") { print_entry("Usage","
$parts{'usage'}
"); } } if($parts{'parameters'} ne "") { print_entry("Parameters","
$parts{'parameters'}
"); } print_entry("Inherits","$parts{'inherits'}"); print_entry("Window","$parts{'window'}"); print_entry("","$parts{'body'}"); print_entry("Description","$parts{'description'}"); if($parts{'switches'} ne "") { print_subtitle("Switches"); print DOCFILE "
\n"; print DOCFILE " \n"; @lines = split("\n","$parts{'switches'}"); $swbody = ""; for(@lines) { if(/!sw:.*/) { if("$swbody" ne "") { print DOCFILE "\n"; $swbody = ""; } $_ =~ s/!sw:[ ]*//g; $_ =~ s/^[ ]*//g; $_ =~ s/\n//gs; $tmp = $_; $tmp =~ s/\(.*\)//g; $tmp =~ s/\$//g; print DOCFILE "\n"; } else { if($swbody ne "") { $swbody="$swbody $_"; } else { $swbody="$_"; } } } if("$swbody" ne "") { print DOCFILE "\n"; } print DOCFILE "
$swbody
$_
$swbody
\n"; print DOCFILE "
\n"; print DOCFILE " \n"; @lines = split("\n","$parts{'functions'}"); $fncbody = ""; for(@lines) { if(/!fn:.*/) { if("$fncbody" ne "") { print DOCFILE "\n"; $fncbody = ""; } $_ =~ s/!fn:[ ]*//g; $_ =~ s/^[ ]*//g; $_ =~ s/\n//gs; $tmp = $_; $tmp =~ s/\(.*\)//g; $tmp =~ s/\$//g; print DOCFILE "\n"; } else { if($fncbody ne "") { $fncbody="$fncbody $_"; } else { $fncbody="$_"; } } } if("$fncbody" ne "") { print DOCFILE "\n"; } print DOCFILE "
$fncbody
$_
$fncbody
\n"; print DOCFILE "
\n"; print DOCFILE " \n"; @lines = split("\n","$parts{'signals'}"); $sigbody = ""; for(@lines) { if(/!sg:.*/) { if("$sigbody" ne "") { print DOCFILE "\n"; $sigbody = ""; } $_ =~ s/!sg:[ ]*//g; $_ =~ s/^[ ]*//g; $_ =~ s/\n//gs; $tmp = $_; $tmp =~ s/\(.*\)//g; $tmp =~ s/\$//g; print DOCFILE "\n"; } else { if($sigbody ne "") { $sigbody="$sigbody $_"; } else { $sigbody="$_"; } } } if("$sigbody" ne "") { print DOCFILE "\n"; } print DOCFILE "
$sigbody
$_
$sigbody
\n"; print DOCFILE "
"; for(@chars) { $alllinks = "$alllinks \n"; $i++; if($i > 13) { $i = 0; $alllinks = "$alllinks\n"; } } $alllinks ="$alllinks
$_
All
"; ##################################### # Simple plain long index $i=0; undef %terms; while($i < $g_shortsIdx{$category}) { $tmp="$category\_$i"; ($cmd,$short,$link) = split("",$g_shorts{$tmp}); $terms{$cmd} = "1"; $commands[$i]=$g_shorts{$tmp}; $commands[$i] =~ s/\n//g; $i++; } ##################################### # Load the other terms from the db (if there) # Make sure that we do not overwrite the current entries if(open(OLDDB,"$g_directory/_db_$category.idx")) { while() { $_ =~ s/\n//g; if($_ ne "") { ($cmd,$short,$link) = split("",$_); if($terms{$cmd} ne "1") { $terms{$cmd} = "1"; $commands[$i]=$_; $i++; } } } close(OLDDB); } $count = $i; ##################################### # Re-dump them if(open(OLDDB,"> $g_directory/_db_$category.idx")) { $i = 0; while($i < $count) { print OLDDB "$commands[$i]\n"; $i++; } close(OLDDB); } @sortedCommands = sort @commands; if(open(CMDINDEX,">$g_directory/doc_$category\_index_all$g_fileextension")) { $g_filehandle=CMDINDEX; print_header("$doctitle: All"); print_tablestart(); print_title("$doctitle: All",""); print_tableend(); print_tablestart(); print_body($alllinks); print_tableend(); print_tablestart(); $i=0; while($i < $count) { ($cmd,$short,$link) = split("",$sortedCommands[$i]); $link =~ s/([a-zA-Z_]*)/\L\1/g; print_twocolumnbody("$cmd",$short); $i++; } print_tableend(); print_tablestart(); print_body($alllinks); print_tableend(); print_footer(); close(CMDINDEX); } else { print "Can't open $g_directory/doc_$category\_index_all$g_fileextension for writing\n"; } ####################### # Alphabetic for(@chars) { if(open(CMDINDEX,">$g_directory/doc_$category\_alphabetic_$_$g_fileextension")) { $upcase=$_; $upcase=~ tr/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/; $g_filehandle=CMDINDEX; print_header("$doctitle: $_"); print_tablestart(); print_title("$doctitle: $_",""); print_tableend(); print_tablestart(); print_body($alllinks); print_tableend(); print_tablestart(); $i=0; $j=0; if($number > 0) { #print("NUMBER > 0,COUNT = $count\n"); while($i < $count) { ($cmd,$short,$link) = split("",$sortedCommands[$i]); #$left=substr($cmd,0,$number); #$right=$cmd; #$right=~ s/^$left//; $left = substr($cmd,0,$number); $right = substr($cmd,$number); $link =~ s/([a-zA-Z_]*)/\L\1/g; #print("RIGHT=$right,_=$_,LEFT=$left,UPCASE=$upcase\n"); if(($right =~ /^$_/) or ($right =~ /^$upcase/) or ($right eq $_)) { $j++; print_twocolumnbody("$left$right",$short); } $i++; } } else { #print("NUMBER == 0,COUNT = $count\n"); while($i < $count) { ($cmd,$short,$link) = split("",$sortedCommands[$i]); $link =~ s/([a-zA-Z_]*)/\L\1/g; if(($cmd =~ /^$_/) || ($cmd =~ /^$upcase/)) { $j++; print_twocolumnbody("$cmd",$short); } $i++; } } if($j == 0) { print_body("No matches"); } print_tableend(); print_tablestart(); print_body($alllinks); print_tableend(); print_footer(); close(CMDINDEX); } else { print "Can't open $g_directory/doc_$category\_alphabetic_$_$g_fileextension for writing\n"; } } } ################################################################################################# # MAIN ################################################################################################# # Force flushing of STDOUT $|=1; # print "--\n"; # print "-- Generating documentation, this may take a while :)\n"; # print "--\n"; # print "-- Extracting keyterms\n"; # Extract the keywords to generate the cross-references $i = 0; $g_numFilesToProcess = @g_filesToProcess; use integer; while($g_filesToProcess[$i] ne "") { if(($i%($g_numFilesToProcess/10)) == 10) { # pad numbers $num = $i*40/$g_numFilesToProcess; if($num<10) { $num = " $num"; } print "[ $num%] Generating documentation: Extracting keyterms (pass 1 of 3)\n"; } extract_keyterms($g_filesToProcess[$i]); $i++; } print "[ 40%] Generating documentation: Extracting keyterms (pass 1 of 3)\n"; $g_files=$i - 1; # print "\n"; # print "-- Extracting documents and generating cross-references\n"; # Sort them @g_keytermsSorted = sort {length($b) <=> length($a)} keys(%g_keyterms); # Process the files now $i = 0; while($g_filesToProcess[$i] ne "") { if(($i%($g_numFilesToProcess/10)) == 10) { # pad numbers $num = 40+($i*40/$g_numFilesToProcess); if($num<10) { $num = " $num"; } print "[ $num%] Generating documentation: Extracting documents (pass 2 of 3)\n"; } process_file($g_filesToProcess[$i]); $i++; } print "[ 80%] Generating documentation: Extracting documents (pass 2 of 3)\n"; # print "\n"; # print "-- Generating indexes\n"; print "[ 82%] Generating documentation: Creating indexes (pass 3 of 3)\n"; generate_indexes("Commands","command",0); print "[ 84%] Generating documentation: Creating indexes (pass 3 of 3)\n"; generate_indexes("Functions","function",1); print "[ 86%] Generating documentation: Creating indexes (pass 3 of 3)\n"; generate_indexes("Modules","module",0); print "[ 88%] Generating documentation: Creating indexes (pass 3 of 3)\n"; generate_indexes("Classes","class",0); print "[ 90%] Generating documentation: Creating indexes (pass 3 of 3)\n"; generate_indexes("Events","event",2); print "[ 92%] Generating documentation: Creating indexes (pass 3 of 3)\n"; generate_indexes("Language Documentation","language",0); print "[ 94%] Generating documentation: Creating indexes (pass 3 of 3)\n"; generate_indexes("Features","widget",0); print "[ 96%] Generating documentation: Creating indexes (pass 3 of 3)\n"; generate_indexes("Misc. Documentation","generic",0); print "[ 98%] Generating documentation: Creating indexes (pass 3 of 3)\n"; generate_indexes("Keyterms & Concepts","keyterms",0); print "[100%] Generating documentation: Creating indexes (pass 3 of 3)\n"; if(open(DOCINDEX,">$g_directory/index$g_fileextension")) { $g_filehandle=DOCINDEX; print_header("Documentation Index"); print_tablestart(); print_twocolumntitle("Index",""); print_twocolumnsubtitle("Fundamentals"); print_twocolumnbody("Introduction to IRC","A \"must read\" for beginners"); print_twocolumnbody("Introduction to KVIrc","A couple of words about KVIrc"); print_twocolumnsubtitle("Scripting Concepts: The KVS Manual"); print_twocolumnbody("Introduction to KVS","Introduction to the KVIrc Scripting Language"); print_twocolumnbody("Basic KVS Concepts","The first steps in the KVS world"); print_twocolumnbody("Aliases and Functions","How to write aliases/functions"); print_twocolumnbody("Variables","Which types of variables are available and how to handle them"); print_twocolumnbody("Operators","Describes simple operations with variables"); print_twocolumnbody("Events","How to handle network events in KVS"); print_twocolumnbody("Objects","Object oriented scripting"); print_twocolumnbody("Addons","How to write nice addons for KVIrc"); print_twocolumnbody("Coding Tips","Some tips that may help you"); print_twocolumnbody("All the language documents","All the documents related to KVS"); print_twocolumnsubtitle("Scripting Reference"); print_twocolumnbody("Commands","The listing of available commands"); print_twocolumnbody("Functions","The listing of available functions"); print_twocolumnbody("Events","The listing of available events"); print_twocolumnbody("Object Classes","The listing of available object classes"); print_twocolumnsubtitle("Other Documents"); print_twocolumnbody("Keyboard shortcuts","Map of the global keyboard shortcuts"); print_twocolumnbody("Modules","Documentation related to specific modules"); # print_twocolumnbody("Features","Documentation on features of KVIrc"); print_twocolumnbody("Miscellaneous","Misc documentation that didn't find any other place"); print_twocolumnbody("Keyterms","The (long) listing of all the keyterms"); print_tableend(); print_footer(); close(DOCINDEX); } else { print "Can't open $g_directory/index$g_fileextension for writing\n"; } if(open(NOHELP,">$g_directory/nohelpavailable$g_fileextension")) { $g_filehandle=NOHELP; print_header("No help available"); print_tablestart(); print_title("No help available",""); print_tableend(); print $g_filehandle "

Sorry :(
Unfortunately there is no documentation related to the item you have selected


\n"; print $g_filehandle "Please try a different search term or take a look at the documentation index "; print $g_filehandle "and try to locate the topic manually.

"; print_footer(); close(NOHELP); } else { printf "Can't open $g_directory/nohelpavailable$g_fileextension for writing\n"; } if(open(TAG,">$g_directory/documentation.$g_version.tag")) { print TAG "dummy\n"; close(TAG); } else { printf "Can't open $g_directory/documentation.$g_version.tag for writing\n"; } # print "\n"; # print "--\n"; # print "-- Done! (Processed $g_files files)\n"; # print "--\n";