#!/usr/bin/perl -w ## # gphelp originally written by Niels Skoruppa for pariGUIde; forked and # maintained by Karim Belabas (since v 1.7, 2002) # # This script generates html documentation of the gp/pari functions # on using the tex documentation as given in chapter 3 of the users manual. # Currently this is a workaround since there seems to exist no reasonable # plain TeX to html converter. Here we just take the outputs of # gphelp -raw and translate them into html form. It will be easy to replace, # in the following code, the use of this function by a more powerful tex2html # translator. # # Usage: gphtml [--dist|--4gui|--base=BASE|--out=OUT|--subsections] # # Without any option this will create, in the directory where you # called, a subdirectory named html, and therein the html documentation. # --base=BASE: where to find PARI's toplevel (mandatory) # --out=OUT: where to output our pages # --dist : add this file and a tar archive of html to html. # --4gui : creates the reference docs for pariguide. # The other options are for debugging purposes or consistency checks only. # # Adjust the three pathes below (look for AdJuSt). ######################################################################### #use strict 'vars'; my ($USERSCH3_TEX, # $HTML, $DATE, $version, $distFlag, $guiFlag, $subsectionsFlag, %pics, %basicFrames, %subsections, %sections, %subsectionsByAl, %fill, %sublabel, %tr, %html, @ou, @shortcuts, ); $DATE = localtime(); ############## # AdJuSt these ############## $base = "/usr/local/src/pari"; # the toplevel PARI/GP sources ######################### # Parse the argument line ######################### $distFlag = $guiFlag = $subsectionsFlag = 0; for (@ARGV) { /--dist/ and do { $distFlag = 1; next;}; /--4gui/ and do { $guiFlag = 1; next;}; /--subsections/ and do { $subsectionsFlag = 1; next;}; /--base=(.*)/ and do { $base = $1; next;}; /--out=(.*)/ and do { $HTML = $1; next;}; &usage; } my ($HTMLdft) = $guiFlag? "./ref": "./html"; if (!$HTML) { $HTML = $HTMLdft; } $ENV{'GPHELP_DOCDIR'} = "$base/doc"; $USERSCH3_TEX = "$base/doc/usersch3.tex"; $gphelp = "$base/doc/gphelp"; sub usage { print STDERR "Usage: $0 [--base=BASE|--out=OUT|--dist|--4gui|--subsections]\n"; exit( 0); } # We see first what information the system has about pari/gp and collect it initVersionAndShortcuts(); initSubsections(); # If we only want to list the subsections of usersch3.tex, then this sub dbgSections { for my $k (sort keys %sections) { print "$k $sections{$k}\n"; } for my $k (sort keys %subsections) { print "\n\n $k\n\n"; for my $i (@{ $subsections{$k} }) { print "\t$i\n"; } } } if ($subsectionsFlag) { dbgSections(); exit(0); } initFixedData(); system( "mkdir -p $HTML"); ####################################################################### # Here we write all *.html files of the pariguide doc ####################################################################### if ($guiFlag) { my ($HEAD) = <<"__UP_TO_HERE__";
Pari/GP Reference Documentation HOME Contents - Global index - GP keyboard shortcuts

__UP_TO_HERE__ writeData(*DATA, 1); # icons writeToC4Ref($HEAD); #toc writeIndex(6, $HEAD); # function index using 6 columns, # subsection pages, for my $k (sort keys %subsections) { &writeEntries4Ref($k, $HEAD); } # and meta commands. writeShortcuts($HEAD); exit(0); }; ####################################################################### # Here we write all *.html files, according to the # frame layout sketched in the data section below (after __DATA__ ). # Change look and feel by altering the descriptions in the data section. ####################################################################### # Write basic frames writeData(*DATA, 0); writeToC(); # ... and the pages for the frames "item" and "entry" for my $k (keys %subsections) { writeFunctionsByCategory($k); &writeEntries($k); } writeModRewrite(); writeShortcuts(""); writeOperators(); writeReadline(); for my $l (sort keys %subsectionsByAl) { writeFunctionsByAlphabet($l) } if ($distFlag) { system("cp gphtml $HTML; H=`basename $HTML`; cd $HTML/..; tar cfz \$H.tgz \$H") } ########### The subroutines ################## sub warning { print STDERR "\t\e[0;31m\e[1mWarning:\e[m ".$_[0]."\n"; } sub fatal { die "\t\e[0;31m\e[1mError:\e[m ".$_[0]."\n"; } sub happy { print STDERR "\t".$_[0]." ...... \e[0;32m\e[1m OK\e[m\n"; } sub unhappy { print STDERR "\t".$_[0]." ...... \e[0;31m\e[1m FAILED\e[m\n"; } ############################################################################### # Sets ups $version and the list @shortcuts of GP keyboard shortcuts. Calls gp! # Checks if gphelp is available ############################################################################### sub initVersionAndShortcuts { my ($gp) = "$base/gp"; my ($v) = `$gp --version-short 2>&1`; if ($v eq "") { fatal( "gp --version-short doesn't work"); } chomp($v); $version = "PARI/GP calculator, version $v"; happy("gp found ($gp, version $v)"); @shortcuts = split "\n", `echo '?\\' | $gp -q --test`; # my ($e) = `$gphelp -raw addprimes`; if ($e eq "") { fatal( "gphelp not found"); } happy("gphelp found ($gphelp)"); } ########################################################################### # Sets up hash of lists %subsections. Keys are the sections of usersch3.tex # Values are the list of corresponding subsections. ########################################################################### sub initSubsections { my($j, $key); open IN, "<$USERSCH3_TEX" or fatal("Cannot open $USERSCH3_TEX: fix the --base argument"); $j = 1; $key = "Dummy"; while () { next if (/^%/); if (s/\\section\{(.*?)\}//) { $key = $1; $subsections{$key} = []; $sections{$j} = $key; $j++; $fill{$key} = cleanid($key); } if (/\\label\{([^}]*)}/) { die "duplicate label: $1" if ($sublabel{$1}); $sublabel{$1} = $fill{$key}; } if( s/\\subseckbd\{(.*?)\}//) { $id = $1; } elsif( s/\\subsecidx\{(.*?)\}//) { $id = $1; } elsif( s/\\subsec\{(.*?)\}//) { $id = $1; $id =~ s/\$\(.*//; # remove arguments $id =~ s/\\//g; } else { next; } push @{ $subsections{$key} }, $id; next if ($id =~ / /); # keep only keywords for index, not all subsections next if ($id !~ /^([a-zA-Z])/); # remove operators my ($letter) = uc($1); push @{ $subsectionsByAl{$letter} }, "[$id]__($key)__\n"; } close IN; } sub GPatEnd { my ($A) = cleankey($a); $A = "ZZZ$A" if ($A =~ /GP/); my ($B) = cleankey($b); $B = "ZZZ$B" if ($B =~ /GP/); $A cmp $B; } # Writes index.html, the entry page for the reference documentation. # Relies on the hash %subsection. sub writeToC4Ref { my ($HEAD) = $_[0]; my ($toc1, $toc2); $toc1 = $toc2 =''; $z = 0; for my $key (sort GPatEnd keys %subsections) { 0 == $z and $toc1 .= "\n"; $toc1 .= "". cleankey($key) . '' . "\n"; 1 == $z and $toc1 .= "\n"; $z = 1 - $z; } 1 == $z and $toc1 .= " \n"; for my $l (sort keys %subsectionsByAl) { $toc2 .= "$l\n"; } my ($txt) = <<"__UP_TO_HERE__"; $HEAD

Functions by Category

$toc1

GP Keyboard Shortcuts


Functions in Alphabetical Order

$toc2


Catalogue of Functions for the $version.
(generated by gphtml on $DATE.)
__UP_TO_HERE__ printHTML("index.html", "Table of Contents", '', $txt); } # Writes toc.html. Relies on the hash %subsection. sub writeToC { my($txt, $toc1, $toc2); $toc1 = $toc2 =''; for my $key (sort GPatEnd keys %subsections) { die "Unknown subsection: $key" if (!defined($fill{$key}) ); $toc1 .= "" . cleankey($key) . "\n
\n"; } for my $l (sort keys %subsectionsByAl) { $toc2 .= " $l\n"; } $txt = <<"__UP_TO_HERE__";
Pari/GP Home Page

Functions by Category

$toc1 GP operators
GP line editor: readline
GP keyboard shortcuts

Functions in Alphabetical Order

$toc2
__UP_TO_HERE__ printHTML("toc.html", "Table of Contents", 'style="background-image:url(toc.jpg)"', $txt); } sub cleankey { my ($k) = $_[0]; $k =~ s/\$//g; $k =~ s/\\bs/\\/g; $k =~ s/\\%/%/g; $k =~ s/\\pow/\^/g; $k; } sub cleanid { my ($k) = $_[0]; $k =~s/\+/plus/g; $k =~s/\-/minus/g; $k =~s/\\/backslash/g; $k =~s/\//slash/g; $k =~s/\%/percent/g; $k =~s/\*/star/g; $k =~ s/[^a-zA-Z0-9]/_/g; $k; } ############################################################################# # Writes, for each list of subsection titles pointed to by $key, an html file # cont_$key.html. This is a collection of links to the respective entries in # $key.html. Uses the hash %subsection. # Call in the form writeFunctionsByCategory($key) ############################################################################# sub writeFunctionsByCategory { my($key, $txt, @A); $key = $_[0]; for my $item (@{$subsections{$key}}) { my ($a, $b) = (cleanid($item), cleankey($item)); push(@A, "$b"); } my ($cleankey) = cleankey($key); $txt = "\n

Index: $cleankey

\n" . '
' . join(",\n", @A) . "\n
"; printHTML("cont_$fill{$key}.html", "$cleankey", '', $txt); } ############################################################################ # Writes function_index.html. This is a collection of links to the respective # entries in the entry pages. Uses the hash %subsectionsByAl. # Call in the form writeIndex(number_of_columns) ############################################################################ sub writeIndex { my ($nCols, $HEAD) = @_; my ($txt); $txt = $HEAD . "

Index

\n" .''."\n"; for my $letter (sort keys %subsectionsByAl) { $txt .= "\n\n"; my ($z) = 1; for my $item (sort @{$subsectionsByAl{$letter}}) { $item =~ /^\[(.*?)\]__\((.*?)\)__$/; if ($z == $nCols) { $z = 1; $txt .= "\n\n\n"; } $txt .= "\n"; $z++; } for(; $z < $nCols; $z++) { $txt .= "\n"; } $txt .= ''."\n"; } $txt .= "
$letter
 $1 
"; printHTML('function_index.html', 'Index', '', $txt); } sub writeModRewrite { my ($f) = "ModRewrite-table"; my ($txt); for my $letter (sort keys %subsectionsByAl) { for my $item (sort @{$subsectionsByAl{$letter}}) { $item =~ /^\[(.*?)\]__\((.*?)\)__$/; $txt .= "$1 $fill{$2}.html#$1\n"; } } open OUT, ">$HTML/$f" or fatal("Cannot create the file $HTML/$f\n"); print OUT $txt; close(OUT); } ############################################################################ # Writes, for each letter the file cont_$letter.html. This is a collection of # links to the respective entries in the entry pages. # Uses the hash %subsectionsByAl. # Call in the form writeFunctionsByAlphabet( $letter) ############################################################################ sub writeFunctionsByAlphabet { my ($letter) = $_[0]; my ($txt) = "\n

Index: $letter

\n";; for my $item (sort @{ $subsectionsByAl{$letter} }) { $item =~ /^\[(.*?)\]__\((.*?)\)__$/; $txt .= "  $1\n"; } printHTML("cont_$letter.html", "$letter", '', $txt); } sub refexpand { my ($c) = $_[0]; my ($p) = $sublabel{$c}; if (!$p) { # warning("missing label $c"); return $c; } "$c<\/a>"; } sub keyrefexpand { my ($c) = $_[0]; my ($p) = $sublabel{'se:' . $c}; if (!$p) { return $c; } "$c<\/a>"; } sub get_entry { my ($item) = @_; my ($l, $r, $d, @names); my (%trans0) = ( # '&' => '&', '<' => '<', '>' => '>', '~{O}' => 'Õ', '\oplus' => '⨁ ', '\bigoplus' => ' ⨁ ', '\bigsqcup' => ' ⨆ ', '\subset' => ' ⊂ ', '\otimes' => ' ⨂ ', '\in' => ' ∈ ', '\bigotimes' => ' ⨂ ', '\to' => ' → ', '\triangleleft' => ' ◃ ', '\geq' => ' ≥ ', '\leq' => ' ≤ ', ':---@[gt]' => ' ⟼ ', '---' => ' — ', ); my (%trans) = ( '\{' => '{', '\}' => '}', '\langle' => '⟨', '\rangle' => '⟩', '@0' => ' ', '@1' => '', '@2' => '', '@3' => '', ); my ($e, $title); $e = `$gphelp -raw -noskip '$item'`; ($e =~ /^'.*' not\ found !$/) and unhappy("\t$item"); # first kill TeX leftovers $e =~ s/\\not *\\in\b/ \∉ /gs; for my $key (keys %trans0) { $l = quotemeta($key); $r = $trans0{$key}; $e =~ s/$l/$r/gs; } $e =~ s/\_\{([^}]*)}/$1<\/sub>/g; $e =~ s/\^\{([^}]*)}/$1<\/sup>/g; # one letter subscripts, otherwise 't_MAT' & co gets mangled $e =~ s/\_([a-zA-Z0-9])\b/$1<\/sub>/g; # Too many mistakes: polynomials in verbatim code :-( # $e =~ s/\^([a-zA-Z0-9])\b/$1<\/sup>/g; $e =~ s/\^\*/*<\/sup>/g; # this one is OK my ($a, $b); # symbols $a = quotemeta('@[startword]'); $b = quotemeta('@[endword]'); $e =~ s/$a([a-zA-Z]*)$b/\&$1;/xg; # calligraphic letters $a = quotemeta('@[startbc]'); $b = quotemeta('@[endbc]'); $e =~ s/$a([A-Z])$b/\&$1scr;/g; # blackboard bold letters $a = quotemeta('@[startbi]'); $b = quotemeta('@[endbi]'); $e =~ s/$a([A-Z])$b/\&$1opf;/g; # Fraktur $a = quotemeta('@[startbg]'); $b = quotemeta('@[endbg]'); $e =~ s/$a([A-Za-z])$b/\&$1fr;/g; #overline $e =~ s/\\(overline|bar)\{([^}]*)\}/$2<\/span>/g; # <=, >= $a = quotemeta('@[startcode]'); $b = quotemeta('@[endcode]'); $e =~ s/$a\@\[lt\]=$b/≤/g; $e =~ s/$a\@\[gt\]=$b/≥/g; $e =~ s/$a(\w+)$b/'@[startcode]' . keyrefexpand($1) . '@[endcode]'/gse; $e =~ s/\@\[startref\]([^\@]*)\@\[endref\]/refexpand($1)/gse; while ($e =~ s/\@\[label ([^\]]*)\]//) { push(@names,$1); } # TODO: Fix the dirty hack from here # handle \bprog @com $e =~ s/(\@1 *\@\[startcode\][^\@]*)\@\[endcode\]([^\n]*)\@\[startcode\]/$1 $2/gs; # handle @com $e =~ s/(\@0[^\@]*)\@\[endcode\]([^\n]*)\@\[startcode\]/$1 $2/gs; $l = '\@1 *\@\[startcode\]'; $r = '

  ';
  $e =~ s/$l/$r/gs;
  $l = '\@[23] *\@\[endcode\]'; $r = '

'; $e =~ s/$l/$r/gs; # to here. for my $key (keys %trans) { $l = quotemeta($key); $r = $trans{$key}; $e =~ s/$l/$r/gs; } # warn about leftovers if ($e =~ /(\\[a-zA-Z]{3,})/) { my ($w) = "$item: $1"; # silence false positive if ($w ne 'se:def,TeXstyle: \right' && $w ne 'se:def,TeXstyle: \def' && $w ne 'ecppexport: \nFormat' && $w ne 'strtex: \pmatrix' && $w ne 'mspolygon: \usepackage' && $w ne 'msfarey: \documentclass' ) { warning $w; } } # then make a nice header $e =~ s/^\@\[startbold](.*?)\:\@\[endbold]\n\n/

/; warning("no title: $item") if (!$1); $title = "

$1<\/h4>"; $title =~ s/, */, /g; # now care for the @[] markers for my $key (@ou) { $l = quotemeta($tr{$key}); $r = $html{$key}; $e =~ s/$l/$r/gs; $title =~ s/$l/$r/gs; } # finally break into paragraphs $e =~ s/\n\n/\<\/p\>\n\/gs; my ($names) = ""; for (@names) { $names .= "
<\/div>\n"; } return ($e, $names, $title); } sub writeEntries4Ref() { my ($key, $HEAD) = @_; my ($cleankey) = cleankey($key); print STDERR "\twriting: $cleankey\n"; # desambiguate between keywords belonging to 2 sections, e.g. 'log' my ($pre) = ($cleankey eq "GP defaults")? "se:def,": ""; my ($toc) = ''; for my $item (sort @{ $subsections{$key} }) { my ($a, $b) = (cleanid($item), cleankey($item)); $toc .= "$b  \n"; } my ($txt) = <<"__UP_TO_HERE__"; $HEAD

$cleankey


__UP_TO_HERE__ my ($e, $names) = get_entry($key); $txt .= ""; for my $item (@{ $subsections{$key} }) { my ($a, $b) = (cleanid($item), cleankey($item)); my ($e, $names) = get_entry("$pre$item"); $txt .= <<"__UP_TO_HERE__"; __UP_TO_HERE__ } $txt .= '
$toc
 
$e
$b HOME   TOP
$e
'; printHTML("$fill{$key}.html", "$key", '', $txt); } # write GP keyboard shortcuts sub writeShortcuts { my ($header) = @_; my ($t,$t2) = ('',''); for (@shortcuts) { if (/^ *([^:].*) *: *(.*) *$/) { $t .= "$1" . "$2\n"; } else { $t2 .= $_; } } $t =<<"__UP_TO_HERE__"; $header

GP Keyboard Shortcuts

$t2 $t
__UP_TO_HERE__ printHTML('keyboard_shortcuts.html', 'GP Keyboard Shortcuts', '', $t); } # write GP readline introduction sub writeReadline { my ($t) = "

GP Line Editor: Readline

\n"; my ($e) = get_entry("readline"); $t .= $e; printHTML('readline.html', 'GP Keyboard Shortcuts', '', $t); } # write GP operators section sub writeOperators { my ($t) = "

GP Operators and their Priorities

\n"; my ($e) = get_entry("operator"); $t .= $e; printHTML('operators.html', 'GP Operators', '', $t); } ########################################################################### # Writes, for each list pointed to by $key, a file $key.html containing the # subsections of the corresponding section in usersch3.tex. Needs %subsections # and uses "gphelp -raw to convert subsections of usersch3.tex into html. # Use in the form writeEntries($key) ########################################################################### sub writeEntries() { my ($key) = $_[0]; my ($cleankey) = cleankey($key); print STDERR "\twriting: $cleankey\n"; # desambiguate between keywords belonging to 2 sections, e.g. 'log' my ($pre) = ($cleankey eq "GP defaults")? "se:def,": ""; my ($e, $names) = get_entry("$key"); my ($txt) = "\n$names

$cleankey

\n\n"; $txt .= $e; # initial text if ($e) { $txt .= "
\n" } for my $item (@{ $subsections{$key} }) { my ($a) = cleanid($item); my ($e,$names,$title) = get_entry("$pre$item"); $txt .= "$names
\n$title\n$e\n
\n"; } printHTML( "$fill{$key}.html", "$cleankey", '', $txt); } # auxilliary for writeData sub printFile { my($skin, $Mode, $data, $parm) = @_; # all skins return if (!$Mode); if ($Mode eq 'TXT') { printTXT(@{$parm}, $data); return; } # no html in ref mode if ($Mode eq 'HTML') { printHTML(@{$parm}, $data) if (!$skin); return; } # PIC: filter out unneeded icons according to skin my ($f) = @{$parm}; # filename return if ($skin && ($f eq 'empty.jpg' || $f eq 'toc.jpg')); return if (!$skin && ($f eq 'home.gif' || $f eq 'top.gif')); $data =~ s/\s//g; printPIC(@{$parm}, $data); } ################################################################ # Writes html pages and images described in file FILE. See below # __DATA__ for the description syntax. # Call in the form writeData (*FILEHANDLE, $skin) 1 for ref/0 else ################################################################ sub writeData { my ($IN, $skin) = @_; my($Mode, @parm, $data); $Mode = ''; while (<$IN>) { if (/^\s*\@PIC\{\s*(.*?)\s*\}/) { @parm = ($1); $data = ''; $Mode = 'PIC'; next; } if (/^\s*\@HTML\{\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\}/) { @parm = ($1, $2, $3); $data = ''; $Mode = 'HTML'; next; } if (/^\s*\@TXT\{\s*(.*?)\}/) { @parm = ($1); $data = ''; $Mode = 'TXT'; next; } if (/\@DONE/) { # print "writing $parm[0]\n"; printFile($skin, $Mode, $data, \@parm); $Mode = ''; next; } next if (!$Mode); # eval. variables in DATA section if ($Mode eq 'HTML') { s/\$(\w+)/${$1}/g; }; $data .= $_; next; } } ################################################################## # Writes an html page to file $HTML/$f. Call in the form # printHTML($name_of_file, $title_of_page, $background, $contents) # with properly initialized scalar arguments. # If $content starts by then no tag is printed ################################################################## sub printHTML { my ($f, $title, $bgd, $con) = @_; my ($DTD); if ($con =~ /^$HTML/$f" or fatal("Cannot create the file $HTML/$f\n"); print OUT <<"__UP_TO_HERE__"; $DTD Catalogue of GP/PARI Functions: $title $meta $con __UP_TO_HERE__ close OUT; } ######################################################## # Writes a stream of 2 digit hex values as chars to file # Call in the form printPIC( $file, $stream) ######################################################## sub printPIC { my ($f, $data) = @_; open OUT, ">${HTML}/$f" or fatal( "Cannot create the file ${HTML}/$f\n"); $data =~ s/(..)/chr(hex($1))/ge; print OUT $data; close OUT; } sub printTXT { my ($f, $data) = @_; open OUT, ">${HTML}/$f" or fatal( "Cannot create the file ${HTML}/$f\n"); print OUT $data; close OUT; } ################DO NOT ALTER BELOW THIS LINE ############################# sub initFixedData { @ou = qw( nbrk dollar startbold endbold startcode endcode startpodcode endpodcode startbi endbi startit endit startword endword startlword endlword pm obr cbr lt gt agrave eacute uuml ouml ); # dollar => ignore # nbrk => ignore # startbold endbold -gp/pari functions => boldface # startcode endcode -??? => color # startpodcode endpodcode -??? => go #startlink endlink -nix da in raw #startbcode endbcode -nix da in raw # startbi endbi -blackboard boldface => boldface # startit endit -optional argments => underline # startword endword -greek letters => color # startlword endlword -math.abbrev. like $\log$ => ignore # pm -+- => #empty gt lt podleader -nix da in raw => ignore # # Neu in parigp.2.1.1: # obr cbr => { } # lt gt => < > # agrave eacute uuml ouml => à ... @tr{@ou} = map "\@[$_]", @ou; %html = ( nbrk => ' ', startbold => '', endbold => '', startcode => '', endcode => '', startpodcode => '', endpodcode => '', startbi => '', endbi => '', startit => '', endit => '', startword => '', endword => '', dollar => '', startlword => '', endlword => '', pm => '±', obr => '{', cbr => '}', lt => '<', gt => '>', agrave => 'à', eacute => 'é', uuml => 'ü', ouml => '¨', ); } __DATA__ Layout of frames: ================= / empty empty empty empty / item index < empty toc ----- empty \ entry \ empty empty title empty @HTML{index.html, Main Page,} @DONE @HTML{empty.html, Empty Page :-), style="background-image:url(empty.jpg)"} @DONE @HTML{title.html, Title Page, style="background-image:url(empty.jpg)"} Catalogue of Functions for the $version.
(generated by gphtml on $DATE.) @DONE @HTML{item.html, Items Page, style="background-color:#FFFFFF;"} @DONE @HTML{entry.html, Welcome Page, style="background-color:#FFFFFF;"}

This is an html documentation of
functions available under the $version.


Comments and proposals for improvement are welcome.

You can download these html files (as gzipped tar file) or generate them by yourself using the perl script gphtml (provided perl, gp, gphelp and the gp/pari tex documentation file usersch3.tex are installed on your system). @DONE @PIC{empty.jpg} ffd8ffe000104a46494600010101004800480000fffe0017437265617465642077697468205468652047494d50ffdb004300080606070605080707070909080a0c140d0c0b0b0c1912130f141d1a1f1e1d1a1c1c20242e2720222c231c1c2837292c30313434341f27393d38323c2e333432ffdb0043010909090c0b0c180d0d1832211c213232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232ffc0001108000a000a03012200021101031101ffc4001500010100000000000000000000000000000006ffc40014100100000000000000000000000000000000ffc4001501010100000000000000000000000000000506ffc40014110100000000000000000000000000000000ffda000c03010002110311003f00b800c261ffd9 @DONE @PIC{toc.jpg} ffd8ffe000104a46494600010101004800480000fffe0017437265617465642077697468205468652047494d50ffdb004300080606070605080707070909080a0c140d0c0b0b0c1912130f141d1a1f1e1d1a1c1c20242e2720222c231c1c2837292c30313434341f27393d38323c2e333432ffdb0043010909090c0b0c180d0d1832211c213232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232ffc00011080014011803012200021101031101ffc40017000101010100000000000000000000000002000106ffc4001510010100000000000000000000000000000001ffc40017010101010100000000000000000000000002010506ffc4001511010100000000000000000000000000000001ffda000c03010002110311003f00ee0a0946c399850861094694128850a10c242850a0c28250a3632362142282510a142830a2146c3810e2146c2184250a1418510a146c646c42850a0c282508a09442850a0c28851b0a0c28850a10c24285128909c01449aae76142484a34a24850a124850a14484a146c490a114490a142892146c3892146c2484a1428921428d8921428512128451242850a24851b0a24850a124850a24909ffd9 @DONE @PIC{home.gif} 47494638396110000d00b30000000000664433995522444444bb6644bb8866aa8888ccbb88bbccddddddddddbb99ffddbbffffddddeeffc0c0c0ffffff21f9040100000c002c0000000010000d0040042c90c949ab7429eb9d9cbf5cd84d5e699614b6391673bedee88a2b4b9a2d18be3a9db12a5acc1614a17a464604003b @DONE @PIC{top.gif} 4749463839610f000b00f10300000000c0c0c0ddddddffffff21f90401000003002c000000000f000b0000025edcb871e3c28d1b376edcb871a1c28d1b376edcb850a2c28d1b376e5c2851a2c28d1b372e942851a2c28d1b17268c283161c28d1b372e94a870e3c68d1b3746949871e3c68d1b174a54b871e3c68d1b234accb871e3c68d0b1326dcb87105003b @DONE @TXT{gphtml.css} table { width: 100%; } img { border: 0px; } table.ref { padding: 0px; border-spacing: 0px; background-color: #FFFFEE; border: 0px;} td.refh { padding: 4px; background-color: #EEEEAA; } tr.spacer { background-color:#FFFFFF; height: 6px; } table.reftop { padding: 2px; border-spacing: 0px; background-color: #83a2ef; border: 0px; } table.toc { padding: 0px; border-spacing: 0px; border: 0px } table.index { padding: 4px; border-spacing: 0px; border: 0px } .shortcuts { padding: 5px; border-spacing: 0; background-color: #83a2ef; border: 1px solid black;} table.shortcuts { border-collapse: collapse; width: 80%; } .right { text-align:right; } .center { text-align:center; } .left { text-align:left; } @DONE