1#!/usr/bin/perl -w 2## 3# gphelp originally written by Niels Skoruppa for pariGUIde; forked and 4# maintained by Karim Belabas (since v 1.7, 2002) 5# 6# This script generates html documentation of the gp/pari functions 7# on using the tex documentation as given in chapter 3 of the users manual. 8# Currently this is a workaround since there seems to exist no reasonable 9# plain TeX to html converter. Here we just take the outputs of 10# gphelp -raw and translate them into html form. It will be easy to replace, 11# in the following code, the use of this function by a more powerful tex2html 12# translator. 13# 14# Usage: gphtml [--dist|--4gui|--base=BASE|--out=OUT|--subsections] 15# 16# Without any option this will create, in the directory where you 17# called, a subdirectory named html, and therein the html documentation. 18# --base=BASE: where to find PARI's toplevel (mandatory) 19# --out=OUT: where to output our pages 20# --dist : add this file and a tar archive of html to html. 21# --4gui : creates the reference docs for pariguide. 22# The other options are for debugging purposes or consistency checks only. 23# 24# Adjust the three pathes below (look for AdJuSt). 25######################################################################### 26 27#use strict 'vars'; 28 29my ($USERSCH3_TEX, 30# $HTML, $DATE, $version, 31 $distFlag, $guiFlag, $subsectionsFlag, 32 %pics, %basicFrames, %subsections, %sections, %subsectionsByAl, %fill, 33 %sublabel, %tr, %html, 34 @ou, @shortcuts, 35 ); 36 37$DATE = localtime(); 38 39############## 40# AdJuSt these 41############## 42$base = "/usr/local/src/pari"; # the toplevel PARI/GP sources 43 44######################### 45# Parse the argument line 46######################### 47$distFlag = $guiFlag = $subsectionsFlag = 0; 48for (@ARGV) { 49 /--dist/ and do { $distFlag = 1; next;}; 50 /--4gui/ and do { $guiFlag = 1; next;}; 51 /--subsections/ and do { $subsectionsFlag = 1; next;}; 52 /--base=(.*)/ and do { $base = $1; next;}; 53 /--out=(.*)/ and do { $HTML = $1; next;}; 54 &usage; 55} 56my ($HTMLdft) = $guiFlag? "./ref": "./html"; 57if (!$HTML) { $HTML = $HTMLdft; } 58$ENV{'GPHELP_DOCDIR'} = "$base/doc"; 59$USERSCH3_TEX = "$base/doc/usersch3.tex"; 60$gphelp = "$base/doc/gphelp"; 61 62sub usage { 63 print STDERR "Usage: $0 [--base=BASE|--out=OUT|--dist|--4gui|--subsections]\n"; 64 exit( 0); 65} 66 67# We see first what information the system has about pari/gp and collect it 68initVersionAndShortcuts(); 69initSubsections(); 70 71# If we only want to list the subsections of usersch3.tex, then this 72sub dbgSections { 73 for my $k (sort keys %sections) { print "$k $sections{$k}\n"; } 74 for my $k (sort keys %subsections) { 75 print "\n\n $k\n\n"; 76 for my $i (@{ $subsections{$k} }) { print "\t$i\n"; } 77 } 78} 79if ($subsectionsFlag) { dbgSections(); exit(0); } 80 81initFixedData(); 82 83system( "mkdir -p $HTML"); 84####################################################################### 85# Here we write all *.html files of the pariguide doc 86####################################################################### 87if ($guiFlag) { 88 my ($HEAD) = <<"__UP_TO_HERE__"; 89<table class="reftop"> 90<tr> 91<td id="top"><b>Pari/GP Reference Documentation</b></td> 92<td class="right"><a href="index.html" 93 ><img alt="HOME" src="./home.gif" /> Contents</a> 94 - <a href="function_index.html">Global index</a> 95 - <a href="keyboard_shortcuts.html">GP keyboard shortcuts</a></td> 96</tr> 97</table><br/> 98 99__UP_TO_HERE__ 100 101 writeData(*DATA, 1); # icons 102 writeToC4Ref($HEAD); #toc 103 writeIndex(6, $HEAD); # function index using 6 columns, 104 # subsection pages, 105 for my $k (sort keys %subsections) { &writeEntries4Ref($k, $HEAD); } 106 # and meta commands. 107 writeShortcuts($HEAD); 108 exit(0); 109}; 110 111####################################################################### 112# Here we write all *.html files, according to the 113# frame layout sketched in the data section below (after __DATA__ ). 114# Change look and feel by altering the descriptions in the data section. 115####################################################################### 116# Write basic frames 117writeData(*DATA, 0); 118writeToC(); 119# ... and the pages for the frames "item" and "entry" 120for my $k (keys %subsections) { 121 writeFunctionsByCategory($k); 122 &writeEntries($k); 123} 124writeModRewrite(); 125writeShortcuts(""); 126writeOperators(); 127writeReadline(); 128for my $l (sort keys %subsectionsByAl) { writeFunctionsByAlphabet($l) } 129if ($distFlag) 130{ system("cp gphtml $HTML; H=`basename $HTML`; cd $HTML/..; tar cfz \$H.tgz \$H") } 131 132########### The subroutines ################## 133sub warning { print STDERR "\t\e[0;31m\e[1mWarning:\e[m ".$_[0]."\n"; } 134sub fatal { die "\t\e[0;31m\e[1mError:\e[m ".$_[0]."\n"; } 135sub happy { print STDERR "\t".$_[0]." ...... \e[0;32m\e[1m OK\e[m\n"; } 136sub unhappy { print STDERR "\t".$_[0]." ...... \e[0;31m\e[1m FAILED\e[m\n"; } 137 138############################################################################### 139# Sets ups $version and the list @shortcuts of GP keyboard shortcuts. Calls gp! 140# Checks if gphelp is available 141############################################################################### 142sub initVersionAndShortcuts { 143 my ($gp) = "$base/gp"; 144 my ($v) = `$gp --version-short 2>&1`; 145 if ($v eq "") { fatal( "gp --version-short doesn't work"); } 146 chomp($v); 147 $version = "PARI/GP calculator, version $v"; 148 happy("gp found ($gp, version $v)"); 149 @shortcuts = split "\n", `echo '?\\' | $gp -q --test`; 150 # 151 my ($e) = `$gphelp -raw addprimes`; 152 if ($e eq "") { fatal( "gphelp not found"); } 153 happy("gphelp found ($gphelp)"); 154} 155 156########################################################################### 157# Sets up hash of lists %subsections. Keys are the sections of usersch3.tex 158# Values are the list of corresponding subsections. 159########################################################################### 160sub initSubsections { 161 my($j, $key); 162 163 open IN, "<$USERSCH3_TEX" 164 or fatal("Cannot open $USERSCH3_TEX: fix the --base argument"); 165 166 $j = 1; $key = "Dummy"; 167 while (<IN>) { 168 next if (/^%/); 169 if (s/\\section\{(.*?)\}//) { 170 $key = $1; 171 $subsections{$key} = []; 172 $sections{$j} = $key; $j++; 173 $fill{$key} = cleanid($key); 174 } 175 if (/\\label\{([^}]*)}/) { 176 die "duplicate label: $1" if ($sublabel{$1}); 177 $sublabel{$1} = $fill{$key}; 178 } 179 if( s/\\subseckbd\{(.*?)\}//) { 180 $id = $1; 181 } 182 elsif( s/\\subsecidx\{(.*?)\}//) { 183 $id = $1; 184 } 185 elsif( s/\\subsec\{(.*?)\}//) { 186 $id = $1; 187 $id =~ s/\$\(.*//; # remove arguments 188 $id =~ s/\\//g; 189 } 190 else { next; } 191 push @{ $subsections{$key} }, $id; 192 next if ($id =~ / /); # keep only keywords for index, not all subsections 193 next if ($id !~ /^([a-zA-Z])/); # remove operators 194 my ($letter) = uc($1); 195 push @{ $subsectionsByAl{$letter} }, "[$id]__($key)__\n"; 196 } 197 close IN; 198} 199 200sub GPatEnd { 201 my ($A) = cleankey($a); $A = "ZZZ$A" if ($A =~ /GP/); 202 my ($B) = cleankey($b); $B = "ZZZ$B" if ($B =~ /GP/); 203 $A cmp $B; 204} 205 206# Writes index.html, the entry page for the reference documentation. 207# Relies on the hash %subsection. 208sub writeToC4Ref { 209 my ($HEAD) = $_[0]; 210 my ($toc1, $toc2); 211 212 $toc1 = $toc2 =''; $z = 0; 213 for my $key (sort GPatEnd keys %subsections) { 214 0 == $z and $toc1 .= "<tr>\n"; 215 $toc1 .= "<td><a href=\"./$fill{$key}.html\">". cleankey($key) . '</a></td>' . "\n"; 216 1 == $z and $toc1 .= "</tr>\n"; 217 $z = 1 - $z; 218 } 219 1 == $z and $toc1 .= "<td> </td>\n</tr>"; 220 221 for my $l (sort keys %subsectionsByAl) { 222 $toc2 .= "<a href = \"./function_index.html#$l\">$l</a>\n"; 223 } 224 225 my ($txt) = <<"__UP_TO_HERE__"; 226$HEAD 227<h3>Functions by Category</h3> 228<table class="toc"> 229$toc1 230</table> 231 232<h4><a href="./keyboard_shortcuts.html">GP Keyboard Shortcuts</a></h4><br/> 233 234<h3>Functions in Alphabetical Order</h3> 235$toc2 236<br><hr><br> 237<small> 238Catalogue of Functions for the $version. 239<br> 240(generated by gphtml on $DATE.)</small> 241__UP_TO_HERE__ 242 243 printHTML("index.html", "Table of Contents", '', $txt); 244} 245 246# Writes toc.html. Relies on the hash %subsection. 247sub writeToC { 248 my($txt, $toc1, $toc2); 249 250 $toc1 = $toc2 =''; 251 for my $key (sort GPatEnd keys %subsections) { 252 die "Unknown subsection: $key" if (!defined($fill{$key}) ); 253 $toc1 .= "<A href=\"./cont_$fill{$key}.html\" target=\"itemFrame\" " 254 . "onClick=\"parent.entryFrame.location='$fill{$key}'\">" 255 . cleankey($key) . "</A>\n<HR>\n"; 256 } 257 for my $l (sort keys %subsectionsByAl) { 258 $toc2 .= " <A href=\"./cont_$l.html\" target=\"itemFrame\">$l</A>\n"; 259 } 260 261 $txt = <<"__UP_TO_HERE__"; 262<div class="center"> 263<A href="https://pari.math.u-bordeaux.fr/" target="_top"> 264<img alt="Pari/GP Home Page" src="https://pari.math.u-bordeaux.fr/site_icons/Logo_PARI-GP_Couleurs_L150px.png"></A> 265</div> 266 267<div class="left"> 268<H4>Functions by Category</H4> 269<small> 270$toc1 271<A href="./operators.html" target="entryFrame">GP operators</A> 272<hr> 273<A href="./readline.html" target="entryFrame">GP line editor: readline</A> 274<hr> 275<A href="./keyboard_shortcuts.html" target="entryFrame">GP keyboard shortcuts</A> 276</small> 277<hr> 278 279<H4>Functions in Alphabetical Order</H4> 280<div style="font-size: 80%; text-align: justify;"> 281$toc2 282</div> 283</div> 284__UP_TO_HERE__ 285 286 printHTML("toc.html", "Table of Contents", 'style="background-image:url(toc.jpg)"', $txt); 287} 288 289sub cleankey { my ($k) = $_[0]; 290 $k =~ s/\$//g; 291 $k =~ s/\\bs/\\/g; 292 $k =~ s/\\%/%/g; 293 $k =~ s/\\pow/\^/g; 294 $k; 295} 296sub cleanid { my ($k) = $_[0]; 297 $k =~s/\+/plus/g; 298 $k =~s/\-/minus/g; 299 $k =~s/\\/backslash/g; 300 $k =~s/\//slash/g; 301 $k =~s/\%/percent/g; 302 $k =~s/\*/star/g; 303 $k =~ s/[^a-zA-Z0-9]/_/g; 304 $k; 305} 306 307############################################################################# 308# Writes, for each list of subsection titles pointed to by $key, an html file 309# cont_$key.html. This is a collection of links to the respective entries in 310# $key.html. Uses the hash %subsection. 311# Call in the form writeFunctionsByCategory($key) 312############################################################################# 313sub writeFunctionsByCategory { 314 my($key, $txt, @A); 315 $key = $_[0]; 316 317 for my $item (@{$subsections{$key}}) { 318 my ($a, $b) = (cleanid($item), cleankey($item)); 319 push(@A, "<A href=\"$fill{$key}.html#$a\" target=\"entryFrame\">$b</A>"); 320 } 321 my ($cleankey) = cleankey($key); 322 $txt = "\n<h3 class=\"center\">Index: $cleankey</h3>\n" 323 . '<div style="font-size: 80%; text-align: justify;">' 324 . join(",\n", @A) 325 . "\n</div>"; 326 printHTML("cont_$fill{$key}.html", "$cleankey", '', $txt); 327} 328 329############################################################################ 330# Writes function_index.html. This is a collection of links to the respective 331# entries in the entry pages. Uses the hash %subsectionsByAl. 332# Call in the form writeIndex(number_of_columns) 333############################################################################ 334sub writeIndex { 335 my ($nCols, $HEAD) = @_; 336 my ($txt); 337 $txt = $HEAD . "<h3 class=\"left\">Index</h3>\n" 338 .'<table class="index">'."\n"; 339 for my $letter (sort keys %subsectionsByAl) { 340 $txt .= "<tr>\n<td id=\"$letter\"><b>$letter</b></td>\n"; 341 my ($z) = 1; 342 for my $item (sort @{$subsectionsByAl{$letter}}) { 343 $item =~ /^\[(.*?)\]__\((.*?)\)__$/; 344 if ($z == $nCols) { $z = 1; $txt .= "</tr>\n<tr>\n<td> </td>\n"; } 345 $txt .= "<td><A href=\"./$fill{$2}.html#$1\">$1</A></td>\n"; 346 $z++; 347 } 348 for(; $z < $nCols; $z++) { $txt .= "<td> </td>\n"; } 349 $txt .= '</tr>'."\n"; 350 } 351 $txt .= "</table>"; 352 printHTML('function_index.html', 'Index', '', $txt); 353} 354 355sub writeModRewrite { 356 my ($f) = "ModRewrite-table"; 357 my ($txt); 358 for my $letter (sort keys %subsectionsByAl) { 359 for my $item (sort @{$subsectionsByAl{$letter}}) { 360 $item =~ /^\[(.*?)\]__\((.*?)\)__$/; 361 $txt .= "$1 $fill{$2}.html#$1\n"; 362 } 363 } 364 open OUT, ">$HTML/$f" or fatal("Cannot create the file $HTML/$f\n"); 365 print OUT $txt; 366 close(OUT); 367} 368 369############################################################################ 370# Writes, for each letter the file cont_$letter.html. This is a collection of 371# links to the respective entries in the entry pages. 372# Uses the hash %subsectionsByAl. 373# Call in the form writeFunctionsByAlphabet( $letter) 374############################################################################ 375sub writeFunctionsByAlphabet { 376 my ($letter) = $_[0]; 377 my ($txt) = "\n<h3 class=\"center\">Index: $letter</h3></div>\n";; 378 for my $item (sort @{ $subsectionsByAl{$letter} }) { 379 $item =~ /^\[(.*?)\]__\((.*?)\)__$/; 380 $txt .= 381 " <A href=\"./$fill{$2}.html#$1\" target=\"entryFrame\">$1</A>\n"; 382 } 383 printHTML("cont_$letter.html", "$letter", '', $txt); 384} 385 386sub refexpand { my ($c) = $_[0]; 387 my ($p) = $sublabel{$c}; 388 if (!$p) 389 { 390# warning("missing label $c"); 391 return $c; 392 } 393 "<a href=\"$p.html\#$c\" 394 onClick=\"parent.itemFrame.location='cont_$p.html'\">$c<\/a>"; 395} 396sub keyrefexpand { my ($c) = $_[0]; 397 my ($p) = $sublabel{'se:' . $c}; 398 if (!$p) { return $c; } 399 "<a href=\"$p.html\#se:$c\" 400 onClick=\"parent.itemFrame.location='cont_$p.html'\">$c<\/a>"; 401} 402 403sub get_entry { 404 my ($item) = @_; 405 my ($l, $r, $d, @names); 406 my (%trans0) = ( 407# '&' => '&', 408 '<' => '<', 409 '>' => '>', 410 '~{O}' => 'Õ', 411 '\oplus' => '⨁ ', 412 '\bigoplus' => ' ⨁ ', 413 '\bigsqcup' => ' ⨆ ', 414 '\subset' => ' ⊂ ', 415 '\otimes' => ' ⨂ ', 416 '\in' => ' ∈ ', 417 '\bigotimes' => ' ⨂ ', 418 '\to' => ' → ', 419 '\triangleleft' => ' ◃ ', 420 '\geq' => ' ≥ ', 421 '\leq' => ' ≤ ', 422 ':---@[gt]' => ' ⟼ ', 423 '---' => ' — ', 424 ); 425 my (%trans) = ( 426 '\{' => '{', 427 '\}' => '}', 428 '\langle' => '⟨', 429 '\rangle' => '⟩', 430 '@0' => ' ', 431 '@1' => '', 432 '@2' => '', 433 '@3' => '', 434 ); 435 436 my ($e, $title); 437 $e = `$gphelp -raw -noskip '$item'`; 438 ($e =~ /^'.*' not\ found !$/) and unhappy("\t$item"); 439 # first kill TeX leftovers 440 $e =~ s/\\not *\\in\b/ \∉ /gs; 441 for my $key (keys %trans0) { 442 $l = quotemeta($key); $r = $trans0{$key}; 443 $e =~ s/$l/$r/gs; 444 } 445 $e =~ s/\_\{([^}]*)}/<sub>$1<\/sub>/g; 446 $e =~ s/\^\{([^}]*)}/<sup>$1<\/sup>/g; 447 # one letter subscripts, otherwise 't_MAT' & co gets mangled 448 $e =~ s/\_([a-zA-Z0-9])\b/<sub>$1<\/sub>/g; 449# Too many mistakes: polynomials in verbatim code :-( 450# $e =~ s/\^([a-zA-Z0-9])\b/<sup>$1<\/sup>/g; 451 $e =~ s/\^\*/<sup>*<\/sup>/g; # this one is OK 452 my ($a, $b); 453 # symbols 454 $a = quotemeta('@[startword]'); 455 $b = quotemeta('@[endword]'); 456 $e =~ s/$a([a-zA-Z]*)$b/\&$1;/xg; 457 # calligraphic letters 458 $a = quotemeta('@[startbc]'); 459 $b = quotemeta('@[endbc]'); 460 $e =~ s/$a([A-Z])$b/\&$1scr;/g; 461 # blackboard bold letters 462 $a = quotemeta('@[startbi]'); 463 $b = quotemeta('@[endbi]'); 464 $e =~ s/$a([A-Z])$b/\&$1opf;/g; 465 # Fraktur 466 $a = quotemeta('@[startbg]'); 467 $b = quotemeta('@[endbg]'); 468 $e =~ s/$a([A-Za-z])$b/\&$1fr;/g; 469 #overline 470 $e =~ s/\\(overline|bar)\{([^}]*)\}/<span style="text-decoration:overline">$2<\/span>/g; 471 # <=, >= 472 $a = quotemeta('@[startcode]'); 473 $b = quotemeta('@[endcode]'); 474 $e =~ s/$a\@\[lt\]=$b/≤/g; 475 $e =~ s/$a\@\[gt\]=$b/≥/g; 476 $e =~ s/$a(\w+)$b/'@[startcode]' . keyrefexpand($1) . '@[endcode]'/gse; 477 478 $e =~ s/\@\[startref\]([^\@]*)\@\[endref\]/refexpand($1)/gse; 479 while ($e =~ s/\@\[label ([^\]]*)\]//) { push(@names,$1); } 480# TODO: Fix the dirty hack from here 481 # handle \bprog @com 482 $e =~ s/(\@1 *\@\[startcode\][^\@]*)\@\[endcode\]([^\n]*)\@\[startcode\]/$1 $2/gs; 483 # handle @com 484 $e =~ s/(\@0[^\@]*)\@\[endcode\]([^\n]*)\@\[startcode\]/$1 $2/gs; 485 $l = '\@1 *\@\[startcode\]'; $r = '</p><pre class="code"> '; 486 $e =~ s/$l/$r/gs; 487 $l = '\@[23] *\@\[endcode\]'; $r = '</pre><p>'; 488 $e =~ s/$l/$r/gs; 489# to here. 490 491 for my $key (keys %trans) { 492 $l = quotemeta($key); $r = $trans{$key}; 493 $e =~ s/$l/$r/gs; 494 } 495 496 # warn about leftovers 497 if ($e =~ /(\\[a-zA-Z]{3,})/) 498 { my ($w) = "$item: $1"; 499 # silence false positive 500 if ($w ne 'se:def,TeXstyle: \right' && 501 $w ne 'se:def,TeXstyle: \def' && 502 $w ne 'ecppexport: \nFormat' && 503 $w ne 'strtex: \pmatrix' && 504 $w ne 'mspolygon: \usepackage' && 505 $w ne 'msfarey: \documentclass' 506 ) { warning $w; } 507 } 508 509 # then make a nice header 510 $e =~ s/^\@\[startbold](.*?)\:\@\[endbold]\n\n/<p>/; 511 warning("no title: $item") if (!$1); 512 $title = "<h4>$1<\/h4>"; 513 $title =~ s/, */, /g; 514 515 # now care for the @[] markers 516 for my $key (@ou) { 517 $l = quotemeta($tr{$key}); $r = $html{$key}; 518 $e =~ s/$l/$r/gs; 519 $title =~ s/$l/$r/gs; 520 } 521 522 # finally break into paragraphs 523 $e =~ s/\n\n/\<\/p\>\n\<p\>/gs; 524 525 my ($names) = ""; 526 for (@names) { $names .= "<div id=\"$_\"><\/div>\n"; } 527 return ($e, $names, $title); 528} 529 530sub writeEntries4Ref() { 531 my ($key, $HEAD) = @_; 532 my ($cleankey) = cleankey($key); 533 print STDERR "\twriting: $cleankey\n"; 534 # desambiguate between keywords belonging to 2 sections, e.g. 'log' 535 my ($pre) = ($cleankey eq "GP defaults")? "se:def,": ""; 536 my ($toc) = ''; 537 for my $item (sort @{ $subsections{$key} }) { 538 my ($a, $b) = (cleanid($item), cleankey($item)); 539 $toc .= "<a href=\"./$fill{$key}.html#$a\">$b</a> \n"; 540 } 541 542 my ($txt) = <<"__UP_TO_HERE__"; 543$HEAD 544<h2 class="left">$cleankey</h2><br/> 545 546<table class="ref"> 547<tr><td colspan=2> 548$toc 549</td></tr> 550<tr><td colspan=2> </td></tr> 551__UP_TO_HERE__ 552 my ($e, $names) = get_entry($key); 553 $txt .= "<tr><td colspan=2>$e</td></tr>"; 554 555 for my $item (@{ $subsections{$key} }) { 556 my ($a, $b) = (cleanid($item), cleankey($item)); 557 my ($e, $names) = get_entry("$pre$item"); 558 559 $txt .= <<"__UP_TO_HERE__"; 560<tr> 561<td class="refh" id="$a"><b>$b</b></td> 562<td class="refh right"> 563<a href="./index.html"><img alt="HOME" src="./home.gif" /></a> 564<a href="#top"><img alt="TOP" src="./top.gif" /></a></td></tr> 565<tr><td class="ref" colspan=2>$e</td></tr> 566<tr class="spacer"><td class="ref" colspan=2></td></tr> 567__UP_TO_HERE__ 568 } 569 $txt .= '</table>'; 570 571 printHTML("$fill{$key}.html", "$key", '', $txt); 572} 573 574# write GP keyboard shortcuts 575sub writeShortcuts { my ($header) = @_; 576 my ($t,$t2) = ('',''); 577 for (@shortcuts) 578 { 579 if (/^ *([^:].*) *: *(.*) *$/) 580 { $t .= "<tr><td class=\"shortcuts\">$1</td>" . 581 "<td class=\"shortcuts\">$2</td></tr>\n"; } 582 else 583 { $t2 .= $_; } 584 } 585 $t =<<"__UP_TO_HERE__"; 586$header 587<h3>GP Keyboard Shortcuts</h3> 588$t2 589<table class="shortcuts"> 590$t 591</table> 592__UP_TO_HERE__ 593 printHTML('keyboard_shortcuts.html', 'GP Keyboard Shortcuts', '', $t); 594} 595# write GP readline introduction 596sub writeReadline { 597 my ($t) = "<h3>GP Line Editor: Readline</h3>\n"; 598 my ($e) = get_entry("readline"); 599 $t .= $e; 600 printHTML('readline.html', 'GP Keyboard Shortcuts', '', $t); 601} 602# write GP operators section 603sub writeOperators { 604 my ($t) = "<h3>GP Operators and their Priorities</h3>\n"; 605 my ($e) = get_entry("operator"); 606 $t .= $e; 607 printHTML('operators.html', 'GP Operators', '', $t); 608} 609 610########################################################################### 611# Writes, for each list pointed to by $key, a file $key.html containing the 612# subsections of the corresponding section in usersch3.tex. Needs %subsections 613# and uses "gphelp -raw to convert subsections of usersch3.tex into html. 614# Use in the form writeEntries($key) 615########################################################################### 616sub writeEntries() { 617 my ($key) = $_[0]; 618 619 my ($cleankey) = cleankey($key); 620 print STDERR "\twriting: $cleankey\n"; 621 # desambiguate between keywords belonging to 2 sections, e.g. 'log' 622 my ($pre) = ($cleankey eq "GP defaults")? "se:def,": ""; 623 my ($e, $names) = get_entry("$key"); 624 my ($txt) = "\n$names<h2 class=\"center\">$cleankey</h2>\n\n"; 625 $txt .= $e; # initial text 626 if ($e) { $txt .= "<hr>\n" } 627 for my $item (@{ $subsections{$key} }) { 628 my ($a) = cleanid($item); 629 my ($e,$names,$title) = get_entry("$pre$item"); 630 $txt .= "$names<div id=\"$a\"></div>\n$title\n$e\n<hr>\n"; 631 } 632 printHTML( "$fill{$key}.html", "$cleankey", '', $txt); 633} 634 635# auxilliary for writeData 636sub printFile { my($skin, $Mode, $data, $parm) = @_; 637 # all skins 638 return if (!$Mode); 639 if ($Mode eq 'TXT') { printTXT(@{$parm}, $data); return; } 640 # no html in ref mode 641 if ($Mode eq 'HTML') { printHTML(@{$parm}, $data) if (!$skin); return; } 642 # PIC: filter out unneeded icons according to skin 643 my ($f) = @{$parm}; # filename 644 return if ($skin && ($f eq 'empty.jpg' || $f eq 'toc.jpg')); 645 return if (!$skin && ($f eq 'home.gif' || $f eq 'top.gif')); 646 $data =~ s/\s//g; printPIC(@{$parm}, $data); 647} 648 649################################################################ 650# Writes html pages and images described in file FILE. See below 651# __DATA__ for the description syntax. 652# Call in the form writeData (*FILEHANDLE, $skin) 1 for ref/0 else 653################################################################ 654sub writeData { 655 my ($IN, $skin) = @_; 656 my($Mode, @parm, $data); 657 658 $Mode = ''; 659 while (<$IN>) { 660 if (/^\s*\@PIC\{\s*(.*?)\s*\}/) { 661 @parm = ($1); 662 $data = ''; $Mode = 'PIC'; next; 663 } 664 if (/^\s*\@HTML\{\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*\}/) { 665 @parm = ($1, $2, $3); 666 $data = ''; $Mode = 'HTML'; next; 667 } 668 if (/^\s*\@TXT\{\s*(.*?)\}/) 669 { 670 @parm = ($1); 671 $data = ''; $Mode = 'TXT'; next; 672 } 673 if (/\@DONE/) { 674# print "writing $parm[0]\n"; 675 printFile($skin, $Mode, $data, \@parm); 676 $Mode = ''; next; 677 } 678 next if (!$Mode); 679 680 # eval. variables in DATA section 681 if ($Mode eq 'HTML') { s/\$(\w+)/${$1}/g; }; 682 $data .= $_; next; 683 } 684} 685 686################################################################## 687# Writes an html page to file $HTML/$f. Call in the form 688# printHTML($name_of_file, $title_of_page, $background, $contents) 689# with properly initialized scalar arguments. 690# If $content starts by <FRAMESET> then no <BODY> tag is printed 691################################################################## 692sub printHTML { my ($f, $title, $bgd, $con) = @_; 693 my ($DTD); 694 if ($con =~ /^<FRAMESET/i) 695 { $DTD = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN">'; } 696 else 697 { 698 $DTD = '<!DOCTYPE html>'; 699 $con = "<body $bgd>$con</body>"; 700 } 701 my ($meta) = ''; 702 $meta = '<meta name="robots" content="noindex">' if ($f =~ /^cont_/); 703 704 open OUT, ">$HTML/$f" or fatal("Cannot create the file $HTML/$f\n"); 705 print OUT <<"__UP_TO_HERE__"; 706$DTD 707<html lang="en"> 708<head> 709 <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> 710 <title>Catalogue of GP/PARI Functions: $title</title> 711 712 <meta name="author" content="Karim Belabas"> 713 <meta name="created" content="$DATE"> 714 <meta name="author-email" content="pari\@math.u-bordeaux.fr"> 715 <meta name="keywords" content="PARI, GP, DOC"> 716 $meta 717 <link rel="stylesheet" href="/pari.css"> 718 <link rel="stylesheet" href="./gphtml.css"> 719</head> 720$con 721__UP_TO_HERE__ 722 close OUT; 723} 724 725######################################################## 726# Writes a stream of 2 digit hex values as chars to file 727# Call in the form printPIC( $file, $stream) 728######################################################## 729sub printPIC { my ($f, $data) = @_; 730 open OUT, ">${HTML}/$f" or fatal( "Cannot create the file ${HTML}/$f\n"); 731 $data =~ s/(..)/chr(hex($1))/ge; 732 print OUT $data; 733 close OUT; 734} 735sub printTXT { my ($f, $data) = @_; 736 open OUT, ">${HTML}/$f" or fatal( "Cannot create the file ${HTML}/$f\n"); 737 print OUT $data; 738 close OUT; 739} 740 741################DO NOT ALTER BELOW THIS LINE ############################# 742sub initFixedData 743{ 744 @ou = qw( 745 nbrk 746 dollar 747 startbold endbold 748 startcode endcode 749 startpodcode endpodcode 750 startbi endbi 751 startit endit 752 startword endword 753 startlword endlword 754 pm 755 obr cbr 756 lt gt 757 agrave eacute uuml ouml 758 ); 759# dollar => ignore 760# nbrk => ignore 761# startbold endbold -gp/pari functions => boldface 762# startcode endcode -??? => color 763# startpodcode endpodcode -??? => go 764#startlink endlink -nix da in raw 765#startbcode endbcode -nix da in raw 766# startbi endbi -blackboard boldface => boldface 767# startit endit -optional argments => underline 768# startword endword -greek letters => color 769# startlword endlword -math.abbrev. like $\log$ => ignore 770# pm -+- => 771#empty gt lt podleader -nix da in raw => ignore 772# 773# Neu in parigp.2.1.1: 774# obr cbr => { } 775# lt gt => < > 776# agrave eacute uuml ouml => à ... 777 778 @tr{@ou} = map "\@[$_]", @ou; 779 780 %html = ( 781 nbrk => ' ', 782 startbold => '<b>', 783 endbold => '</b>', 784 startcode => '<code>', 785 endcode => '</code>', 786 startpodcode => '', 787 endpodcode => '', 788 startbi => '<b>', 789 endbi => '</b>', 790 startit => '<em>', 791 endit => '</em>', 792 startword => '<font color=#FF0000>', 793 endword => '</font>', 794 dollar => '', 795 startlword => '', 796 endlword => '', 797 pm => '±', 798 obr => '{', 799 cbr => '}', 800 lt => '<', 801 gt => '>', 802 agrave => 'à', 803 eacute => 'é', 804 uuml => 'ü', 805 ouml => '¨', 806 ); 807} 808 809__DATA__ 810 811Layout of frames: 812================= 813 814 / empty empty empty empty 815 / item 816 index < empty toc ----- empty 817 \ entry 818 \ empty empty title empty 819 820@HTML{index.html, Main Page,} 821<FRAMESET COLS="1%,280,*,1%" ROWS="1%,91%,8%" BORDER=0 FRAMEBORDER="no" FRAMESPACING=0> 822<FRAME src="empty.html" scrolling="no" style="border:none"> 823<FRAME src="empty.html" scrolling="no" style="border:none"> 824<FRAME src="empty.html" scrolling="no" style="border:none"> 825<FRAME src="empty.html" scrolling="no" style="border:none"> 826 827<FRAME src="empty.html" scrolling="no" style="border:none"> 828<FRAME src="toc.html" style="border:none"> 829<FRAMESET rows="140,*" border=0 frameborder="yes" framespacing=0> 830<FRAME name="itemFrame" src="item.html"> 831<FRAME name="entryFrame" src="entry.html"> 832</FRAMESET> 833<FRAME src="empty.html" scrolling="no"> 834 835<FRAME src="empty.html" scrolling="no"> 836<FRAME src="empty.html" scrolling="no"> 837<FRAME src="title.html" scrolling="no"> 838<FRAME src="empty.html" scrolling="no"> 839</FRAMESET> 840@DONE 841 842@HTML{empty.html, Empty Page :-), style="background-image:url(empty.jpg)"} 843@DONE 844 845@HTML{title.html, Title Page, style="background-image:url(empty.jpg)"} 846Catalogue of Functions for the $version. 847<br> 848<small>(generated by gphtml on $DATE.)</small> 849@DONE 850 851@HTML{item.html, Items Page, style="background-color:#FFFFFF;"} 852@DONE 853 854@HTML{entry.html, Welcome Page, style="background-color:#FFFFFF;"} 855<br><br> 856<center> 857<h2>This is an html documentation of<br> 858functions available under the $version.</h2> 859</center> 860<br> 861Comments and proposals for improvement 862<a href="mailto:pari@math.u-bordeaux.fr"> 863are welcome</a>. 864<br> 865<br> 866You can <a href="../$HTML.tgz">download these html files</a> (as gzipped tar 867file) or generate them by yourself using the perl script 868<a href="../gphtml">gphtml</a> (provided perl, gp, gphelp and the gp/pari tex 869documentation file usersch3.tex are installed on your system). 870@DONE 871 872@PIC{empty.jpg} 873ffd8ffe000104a46494600010101004800480000fffe0017437265617465642077697468205468652047494d50ffdb004300080606070605080707070909080a0c140d0c0b0b0c1912130f141d1a1f1e1d1a1c1c20242e2720222c231c1c2837292c30313434341f27393d38323c2e333432ffdb0043010909090c0b0c180d0d1832211c213232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232ffc0001108000a000a03012200021101031101ffc4001500010100000000000000000000000000000006ffc40014100100000000000000000000000000000000ffc4001501010100000000000000000000000000000506ffc40014110100000000000000000000000000000000ffda000c03010002110311003f00b800c261ffd9 874@DONE 875 876@PIC{toc.jpg} 877ffd8ffe000104a46494600010101004800480000fffe0017437265617465642077697468205468652047494d50ffdb004300080606070605080707070909080a0c140d0c0b0b0c1912130f141d1a1f1e1d1a1c1c20242e2720222c231c1c2837292c30313434341f27393d38323c2e333432ffdb0043010909090c0b0c180d0d1832211c213232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232323232ffc00011080014011803012200021101031101ffc40017000101010100000000000000000000000002000106ffc4001510010100000000000000000000000000000001ffc40017010101010100000000000000000000000002010506ffc4001511010100000000000000000000000000000001ffda000c03010002110311003f00ee0a0946c399850861094694128850a10c242850a0c28250a3632362142282510a142830a2146c3810e2146c2184250a1418510a146c646c42850a0c282508a09442850a0c28851b0a0c28850a10c24285128909c01449aae76142484a34a24850a124850a14484a146c490a114490a142892146c3892146c2484a1428921428d8921428512128451242850a24851b0a24850a124850a24909ffd9 878@DONE 879 880@PIC{home.gif} 88147494638396110000d00b30000000000664433995522444444bb6644bb8866aa8888ccbb88bbccddddddddddbb99ffddbbffffddddeeffc0c0c0ffffff21f9040100000c002c0000000010000d0040042c90c949ab7429eb9d9cbf5cd84d5e699614b6391673bedee88a2b4b9a2d18be3a9db12a5acc1614a17a464604003b 882@DONE 883 884@PIC{top.gif} 8854749463839610f000b00f10300000000c0c0c0ddddddffffff21f90401000003002c000000000f000b0000025edcb871e3c28d1b376edcb871a1c28d1b376edcb850a2c28d1b376e5c2851a2c28d1b372e942851a2c28d1b17268c283161c28d1b372e94a870e3c68d1b3746949871e3c68d1b174a54b871e3c68d1b234accb871e3c68d0b1326dcb87105003b 886@DONE 887 888@TXT{gphtml.css} 889table { width: 100%; } 890img { border: 0px; } 891 892table.ref { padding: 0px; border-spacing: 0px; background-color: #FFFFEE; 893 border: 0px;} 894td.refh { padding: 4px; background-color: #EEEEAA; } 895tr.spacer { background-color:#FFFFFF; height: 6px; } 896table.reftop { padding: 2px; border-spacing: 0px; background-color: #83a2ef; 897 border: 0px; } 898table.toc { padding: 0px; border-spacing: 0px; border: 0px } 899table.index { padding: 4px; border-spacing: 0px; border: 0px } 900 901.shortcuts { padding: 5px; border-spacing: 0; background-color: #83a2ef; 902 border: 1px solid black;} 903table.shortcuts { border-collapse: collapse; width: 80%; } 904 905.right { text-align:right; } 906.center { text-align:center; } 907.left { text-align:left; } 908@DONE 909