diff options
author | H. Peter Anvin <hpa@zytor.com> | 2002-04-30 20:52:49 +0000 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2002-04-30 20:52:49 +0000 |
commit | 76690a12ad212d1f77cd1f71d7ac5a9de6eaefb6 (patch) | |
tree | 6d1fe5322184b3e53a9378ce65f6a95f05b59f28 /doc/rdsrc.pl | |
parent | 6768eb71d8debde65562619c938b997aea1bd9f9 (diff) | |
download | nasm-76690a12ad212d1f77cd1f71d7ac5a9de6eaefb6.tar.gz nasm-76690a12ad212d1f77cd1f71d7ac5a9de6eaefb6.tar.bz2 nasm-76690a12ad212d1f77cd1f71d7ac5a9de6eaefb6.zip |
NASM 0.96
Diffstat (limited to 'doc/rdsrc.pl')
-rw-r--r-- | doc/rdsrc.pl | 2134 |
1 files changed, 2134 insertions, 0 deletions
diff --git a/doc/rdsrc.pl b/doc/rdsrc.pl new file mode 100644 index 0000000..1a98128 --- /dev/null +++ b/doc/rdsrc.pl @@ -0,0 +1,2134 @@ +#!/usr/bin/perl + +# Read the source-form of the NASM manual and generate the various +# output forms. + +# TODO: +# +# PS output: +# - show page numbers in printed output +# - think about double-sided support (start all chapters on RHS, +# ie odd-numbered, pages). +# +# Ellipsis support would be nice. + +# Source-form features: +# --------------------- +# +# Bullet \b +# Bullets the paragraph. Rest of paragraph is indented to cope. In +# HTML, consecutive groups of bulleted paragraphs become unordered +# lists. +# +# Emphasis \e{foobar} +# produces `_foobar_' in text and italics in HTML, PS, RTF +# +# Inline code \c{foobar} +# produces ``foobar'' in text, and fixed-pitch font in HTML, PS, RTF +# +# Display code +# \c line one +# \c line two +# produces fixed-pitch font where appropriate, and doesn't break +# pages except sufficiently far into the middle of a display. +# +# Chapter, header and subheader +# \C{intro} Introduction +# \H{whatsnasm} What is NASM? +# \S{free} NASM Is Free +# dealt with as appropriate. Chapters begin on new sides, possibly +# even new _pages_. (Sub)?headers are good places to begin new +# pages. Just _after_ a (sub)?header isn't. +# The keywords can be substituted with \K and \k. +# +# Keyword \K{cintro} \k{cintro} +# Expands to `Chapter 1', `Section 1.1', `Section 1.1.1'. \K has an +# initial capital whereas \k doesn't. In HTML, will produce +# hyperlinks. +# +# Web link \W{http://foobar/}{text} or \W{mailto:me@here}\c{me@here} +# the \W prefix is ignored except in HTML; in HTML the last part +# becomes a hyperlink to the first part. +# +# Literals \{ \} \\ +# In case it's necessary, they expand to the real versions. +# +# Nonbreaking hyphen \- +# Need more be said? +# +# Source comment \# +# Causes everything after it on the line to be ignored by the +# source-form processor. +# +# Indexable word \i{foobar} (or \i\e{foobar} or \i\c{foobar}, equally) +# makes word appear in index, referenced to that point +# \i\c comes up in code style even in the index; \i\e doesn't come +# up in emphasised style. +# +# Indexable non-displayed word \I{foobar} or \I\c{foobar} +# just as \i{foobar} except that nothing is displayed for it +# +# Index rewrite +# \IR{foobar} \c{foobar} operator, uses of +# tidies up the appearance in the index of something the \i or \I +# operator was applied to +# +# Index alias +# \IA{foobar}{bazquux} +# aliases one index tag (as might be supplied to \i or \I) to +# another, so that \I{foobar} has the effect of \I{bazquux}, and +# \i{foobar} has the effect of \I{bazquux}foobar + +$diag = 1, shift @ARGV if $ARGV[0] eq "-d"; + +$| = 1; + +$tstruct_previtem = $node = "Top"; +$nodes = ($node); +$tstruct_level{$tstruct_previtem} = 0; +$tstruct_last[$tstruct_level{$tstruct_previtem}] = $tstruct_previtem; +$MAXLEVEL = 10; # really 3, but play safe ;-) + +# Read the file; pass a paragraph at a time to the paragraph processor. +print "Reading input..."; +$pname = "para000000"; +@pnames = @pflags = (); +$para = undef; +while (<>) { + chomp; + if (!/\S/ || /^\\I[AR]/) { # special case: \I[AR] implies new-paragraph + &got_para($para); + $para = undef; + } + if (/\S/) { + s/\\#.*$//; # strip comments + $para .= " " . $_; + } +} +&got_para($para); +print "done.\n"; + +# Now we've read in the entire document and we know what all the +# heading keywords refer to. Go through and fix up the \k references. +print "Fixing up cross-references..."; +&fixup_xrefs; +print "done.\n"; + +# Sort the index tags, according to the slightly odd order I've decided on. +print "Sorting index tags..."; +&indexsort; +print "done.\n"; + +if ($diag) { + print "Writing index-diagnostic file..."; + &indexdiag; + print "done.\n"; +} + +# OK. Write out the various output files. +print "Producing text output: "; +&write_txt; +print "done.\n"; +print "Producing HTML output: "; +&write_html; +print "done.\n"; +print "Producing PostScript output: "; +&write_ps; +print "done.\n"; +print "Producing Texinfo output: "; +&write_texi; +print "done.\n"; +print "Producing WinHelp output: "; +&write_hlp; +print "done.\n"; + +sub got_para { + local ($_) = @_; + my $pflags = "", $i, $w, $l, $t; + return if !/\S/; + + @$pname = (); + + # Strip off _leading_ spaces, then determine type of paragraph. + s/^\s*//; + $irewrite = undef; + if (/^\\c[^{]/) { + # A code paragraph. The paragraph-array will contain the simple + # strings which form each line of the paragraph. + $pflags = "code"; + while (/^\\c (([^\\]|\\[^c])*)(.*)$/) { + $l = $1; + $_ = $3; + $l =~ s/\\{/{/g; + $l =~ s/\\}/}/g; + $l =~ s/\\\\/\\/g; + push @$pname, $l; + } + $_ = ''; # suppress word-by-word code + } elsif (/^\\C/) { + # A chapter heading. Define the keyword and allocate a chapter + # number. + $cnum++; + $hnum = 0; + $snum = 0; + $xref = "chapter-$cnum"; + $pflags = "chap $cnum :$xref"; + die "badly formatted chapter heading: $_\n" if !/^\\C{([^}]*)}\s*(.*)$/; + $refs{$1} = "chapter $cnum"; + $node = "Chapter $cnum"; + &add_item($node, 1); + $xrefnodes{$node} = $xref; $nodexrefs{$xref} = $node; + $xrefs{$1} = $xref; + $_ = $2; + # the standard word-by-word code will happen next + } elsif (/^\\A/) { + # An appendix heading. Define the keyword and allocate an appendix + # letter. + $cnum++; + $cnum = 'A' if $cnum =~ /[0-9]+/; + $hnum = 0; + $snum = 0; + $xref = "appendix-$cnum"; + $pflags = "appn $cnum :$xref"; + die "badly formatted appendix heading: $_\n" if !/^\\A{([^}]*)}\s*(.*)$/; + $refs{$1} = "appendix $cnum"; + $node = "Appendix $cnum"; + &add_item($node, 1); + $xrefnodes{$node} = $xref; $nodexrefs{$xref} = $node; + $xrefs{$1} = $xref; + $_ = $2; + # the standard word-by-word code will happen next + } elsif (/^\\H/) { + # A major heading. Define the keyword and allocate a section number. + $hnum++; + $snum = 0; + $xref = "section-$cnum.$hnum"; + $pflags = "head $cnum.$hnum :$xref"; + die "badly formatted heading: $_\n" if !/^\\[HP]{([^}]*)}\s*(.*)$/; + $refs{$1} = "section $cnum.$hnum"; + $node = "Section $cnum.$hnum"; + &add_item($node, 2); + $xrefnodes{$node} = $xref; $nodexrefs{$xref} = $node; + $xrefs{$1} = $xref; + $_ = $2; + # the standard word-by-word code will happen next + } elsif (/^\\S/) { + # A sub-heading. Define the keyword and allocate a section number. + $snum++; + $xref = "section-$cnum.$hnum.$snum"; + $pflags = "subh $cnum.$hnum.$snum :$xref"; + die "badly formatted subheading: $_\n" if !/^\\S{([^}]*)}\s*(.*)$/; + $refs{$1} = "section $cnum.$hnum.$snum"; + $node = "Section $cnum.$hnum.$snum"; + &add_item($node, 3); + $xrefnodes{$node} = $xref; $nodexrefs{$xref} = $node; + $xrefs{$1} = $xref; + $_ = $2; + # the standard word-by-word code will happen next + } elsif (/^\\IR/) { + # An index-rewrite. + die "badly formatted index rewrite: $_\n" if !/^\\IR{([^}]*)}\s*(.*)$/; + $irewrite = $1; + $_ = $2; + # the standard word-by-word code will happen next + } elsif (/^\\IA/) { + # An index-alias. + die "badly formatted index alias: $_\n" if !/^\\IA{([^}]*)}{([^}]*)}\s*$/; + $idxalias{$1} = $2; + return; # avoid word-by-word code + } elsif (/^\\b/) { + # A bulleted paragraph. Strip off the initial \b and let the + # word-by-word code take care of the rest. + $pflags = "bull"; + s/^\\b\s*//; + } else { + # A normal paragraph. Just set $pflags: the word-by-word code does + # the rest. + $pflags = "norm"; + } + + # The word-by-word code: unless @$pname is already defined (which it + # will be in the case of a code paragraph), split the paragraph up + # into words and push each on @$pname. + # + # Each thing pushed on @$pname should have a two-character type + # code followed by the text. + # + # Type codes are: + # "n " for normal + # "da" for a dash + # "es" for first emphasised word in emphasised bit + # "e " for emphasised in mid-emphasised-bit + # "ee" for last emphasised word in emphasised bit + # "eo" for single (only) emphasised word + # "c " for code + # "k " for cross-ref + # "kK" for capitalised cross-ref + # "w " for Web link + # "wc" for code-type Web link + # "x " for beginning of resolved cross-ref; generates no visible output, + # and the text is the cross-reference code + # "xe" for end of resolved cross-ref; text is same as for "x ". + # "i " for point to be indexed: the text is the internal index into the + # index-items arrays + # "sp" for space + while (/\S/) { + s/^\s*//, push @$pname, "sp" if /^\s/; + $indexing = $qindex = 0; + if (/^(\\[iI])?\\c/) { + $qindex = 1 if $1 eq "\\I"; + $indexing = 1, s/^\\[iI]// if $1; + s/^\\c//; + die "badly formatted \\c: \\c$_\n" if !/{(([^\\}]|\\.)*)}(.*)$/; + $w = $1; + $_ = $3; + $w =~ s/\\{/{/g; + $w =~ s/\\}/}/g; + $w =~ s/\\-/-/g; + $w =~ s/\\\\/\\/g; + (push @$pname,"i"),$lastp = $#$pname if $indexing; + push @$pname,"c $w" if !$qindex; + $$pname[$lastp] = &addidx($node, $w, "c $w") if $indexing; + } elsif (/^\\[iIe]/) { + /^(\\[iI])?(\\e)?/; + $emph = 0; + $qindex = 1 if $1 eq "\\I"; + $indexing = 1, $type = "\\i" if $1; + $emph = 1, $type = "\\e" if $2; + s/^(\\[iI])?(\\e?)//; + die "badly formatted $type: $type$_\n" if !/{(([^\\}]|\\.)*)}(.*)$/; + $w = $1; + $_ = $3; + $w =~ s/\\{/{/g; + $w =~ s/\\}/}/g; + $w =~ s/\\-/-/g; + $w =~ s/\\\\/\\/g; + $t = $emph ? "es" : "n "; + @ientry = (); + (push @$pname,"i"),$lastp = $#$pname if $indexing; + foreach $i (split /\s+/,$w) { # \e and \i can be multiple words + push @$pname,"$t$i","sp" if !$qindex; + ($ii=$i) =~ tr/A-Z/a-z/, push @ientry,"n $ii","sp" if $indexing; + $t = $emph ? "e " : "n "; + } + $w =~ tr/A-Z/a-z/, pop @ientry if $indexing; + $$pname[$lastp] = &addidx($node, $w, @ientry) if $indexing; + pop @$pname if !$qindex; # remove final space + if (substr($$pname[$#$pname],0,2) eq "es" && !$qindex) { + substr($$pname[$#$pname],0,2) = "eo"; + } elsif ($emph && !$qindex) { + substr($$pname[$#$pname],0,2) = "ee"; + } + } elsif (/^\\[kK]/) { + $t = "k "; + $t = "kK" if /^\\K/; + s/^\\[kK]//; + die "badly formatted \\k: \\c$_\n" if !/{([^}]*)}(.*)$/; + $_ = $2; + push @$pname,"$t$1"; + } elsif (/^\\W/) { + s/^\\W//; + die "badly formatted \\W: \\W$_\n" + if !/{([^}]*)}(\\i)?(\\c)?{(([^\\}]|\\.)*)}(.*)$/; + $l = $1; + $w = $4; + $_ = $6; + $t = "w "; + $t = "wc" if $3 eq "\\c"; + $indexing = 1 if $2; + $w =~ s/\\{/{/g; + $w =~ s/\\}/}/g; + $w =~ s/\\-/-/g; + $w =~ s/\\\\/\\/g; + (push @$pname,"i"),$lastp = $#$pname if $indexing; + push @$pname,"$t<$l>$w"; + $$pname[$lastp] = &addidx($node, $w, "c $w") if $indexing; + } else { + die "what the hell? $_\n" if !/^(([^\s\\\-]|\\[\\{}\-])*-?)(.*)$/; + die "painful death! $_\n" if !length $1; + $w = $1; + $_ = $3; + $w =~ s/\\{/{/g; + $w =~ s/\\}/}/g; + $w =~ s/\\-/-/g; + $w =~ s/\\\\/\\/g; + if ($w eq "-") { + push @$pname,"da"; + } else { + push @$pname,"n $w"; + } + } + } + if ($irewrite ne undef) { + &addidx(undef, $irewrite, @$pname); + @$pname = (); + } else { + push @pnames, $pname; + push @pflags, $pflags; + $pname++; + } +} + +sub addidx { + my ($node, $text, @ientry) = @_; + $text = $idxalias{$text} || $text; + if ($node eq undef || !$idxmap{$text}) { + @$ientry = @ientry; + $idxmap{$text} = $ientry; + $ientry++; + } + if ($node) { + $idxnodes{$node,$text} = 1; + return "i $text"; + } +} + +sub indexsort { + my $iitem, $ientry, $i, $piitem, $pcval, $cval, $clrcval; + + @itags = map { # get back the original data as the 1st elt of each list + $_->[0] + } sort { # compare auxiliary (non-first) elements of lists + $a->[1] cmp $b->[1] || + $a->[2] cmp $b->[2] || + $a->[0] cmp $b->[0] + } map { # transform array into list of 3-element lists + my $ientry = $idxmap{$_}; + my $a = substr($$ientry[0],2); + $a =~ tr/A-Za-z//cd; + [$_, uc($a), substr($$ientry[0],0,2)] + } keys %idxmap; + + # Having done that, check for comma-hood. + $cval = 0; + foreach $iitem (@itags) { + $ientry = $idxmap{$iitem}; + $clrcval = 1; + $pcval = $cval; + FL:for ($i=0; $i <= $#$ientry; $i++) { + if ($$ientry[$i] =~ /^(n .*,)(.*)/) { + $$ientry[$i] = $1; + splice @$ientry,$i+1,0,"n $2" if length $2; + $commapos{$iitem} = $i+1; + $cval = join("\002", @$ientry[0..$i]); + $clrcval = 0; + last FL; + } + } + $cval = undef if $clrcval; + $commanext{$iitem} = $commaafter{$piitem} = 1 + if $cval and ($cval eq $pcval); + $piitem = $iitem; + } +} + +sub indexdiag { + my $iitem,$ientry,$w,$ww,$foo,$node; + open INDEXDIAG,">index.diag"; + foreach $iitem (@itags) { + $ientry = $idxmap{$iitem}; + print INDEXDIAG "<$iitem> "; + foreach $w (@$ientry) { + $ww = &word_txt($w); + print INDEXDIAG $ww unless $ww eq "\001"; + } + print INDEXDIAG ":"; + $foo = " "; + foreach $node (@nodes) { + (print INDEXDIAG $foo,$node), $foo = ", " if $idxnodes{$node,$iitem}; + } + print INDEXDIAG "\n"; + } + close INDEXDIAG; +} + +sub fixup_xrefs { + my $pname, $p, $i, $j, $k, $caps, @repl; + + for ($p=0; $p<=$#pnames; $p++) { + next if $pflags[$p] eq "code"; + $pname = $pnames[$p]; + for ($i=$#$pname; $i >= 0; $i--) { + if ($$pname[$i] =~ /^k/) { + $k = $$pname[$i]; + $caps = ($k =~ /^kK/); + $k = substr($k,2); + $repl = $refs{$k}; + die "undefined keyword `$k'\n" unless $repl; + substr($repl,0,1) =~ tr/a-z/A-Z/ if $caps; + @repl = (); + push @repl,"x $xrefs{$k}"; + foreach $j (split /\s+/,$repl) { + push @repl,"n $j"; + push @repl,"sp"; + } + pop @repl; # remove final space + push @repl,"xe$xrefs{$k}"; + splice @$pname,$i,1,@repl; + } + } + } +} + +sub write_txt { + # This is called from the top level, so I won't bother using + # my or local. + + # Open file. + print "writing file..."; + open TEXT,">nasmdoc.txt"; + select TEXT; + + # Preamble. + $title = "The Netwide Assembler: NASM"; + $spaces = ' ' x ((75-(length $title))/2); + ($underscore = $title) =~ s/./=/g; + print "$spaces$title\n$spaces$underscore\n"; + + for ($para = 0; $para <= $#pnames; $para++) { + $pname = $pnames[$para]; + $pflags = $pflags[$para]; + $ptype = substr($pflags,0,4); + + print "\n"; # always one of these before a new paragraph + + if ($ptype eq "chap") { + # Chapter heading. "Chapter N: Title" followed by a line of + # minus signs. + $pflags =~ /chap (.*) :(.*)/; + $title = "Chapter $1: "; + foreach $i (@$pname) { + $ww = &word_txt($i); + $title .= $ww unless $ww eq "\001"; + } + print "$title\n"; + $title =~ s/./-/g; + print "$title\n"; + } elsif ($ptype eq "appn") { + # Appendix heading. "Appendix N: Title" followed by a line of + # minus signs. + $pflags =~ /appn (.*) :(.*)/; + $title = "Appendix $1: "; + foreach $i (@$pname) { + $ww = &word_txt($i); + $title .= $ww unless $ww eq "\001"; + } + print "$title\n"; + $title =~ s/./-/g; + print "$title\n"; + } elsif ($ptype eq "head" || $ptype eq "subh") { + # Heading or subheading. Just a number and some text. + $pflags =~ /.... (.*) :(.*)/; + $title = sprintf "%6s ", $1; + foreach $i (@$pname) { + $ww = &word_txt($i); + $title .= $ww unless $ww eq "\001"; + } + print "$title\n"; + } elsif ($ptype eq "code") { + # Code paragraph. Emit each line with a seven character indent. + foreach $i (@$pname) { + warn "code line longer than 68 chars: $i\n" if length $i > 68; + print ' 'x7, $i, "\n"; + } + } elsif ($ptype eq "bull" || $ptype eq "norm") { + # Ordinary paragraph, optionally bulleted. We wrap, with ragged + # 75-char right margin and either 7 or 11 char left margin + # depending on bullets. + if ($ptype eq "bull") { + $line = ' 'x7 . '(*) '; + $next = ' 'x11; + } else { + $line = $next = ' 'x7; + } + @a = @$pname; + $wd = $wprev = ''; + do { + do { $w = &word_txt(shift @a) } while $w eq "\001"; # nasty hack + $wd .= $wprev; + if ($wprev =~ /-$/ || $w eq ' ' || $w eq '' || $w eq undef) { + if (length ($line . $wd) > 75) { + $line =~ s/\s*$//; # trim trailing spaces + print "$line\n"; + $line = $next; + $wd =~ s/^\s*//; # trim leading spaces + } + $line .= $wd; + $wd = ''; + } + $wprev = $w; + } while ($w ne '' && $w ne undef); + if ($line =~ /\S/) { + $line =~ s/\s*$//; # trim trailing spaces + print "$line\n"; + } + } + } + + # Close file. + select STDOUT; + close TEXT; +} + +sub word_txt { + my ($w) = @_; + my $wtype, $wmajt; + + return undef if $w eq '' || $w eq undef; + $wtype = substr($w,0,2); + $wmajt = substr($wtype,0,1); + $w = substr($w,2); + $w =~ s/<.*>// if $wmajt eq "w"; # remove web links + if ($wmajt eq "n" || $wtype eq "e " || $wtype eq "w ") { + return $w; + } elsif ($wtype eq "sp") { + return ' '; + } elsif ($wtype eq "da") { + return '-'; + } elsif ($wmajt eq "c" || $wtype eq "wc") { + return "`${w}'"; + } elsif ($wtype eq "es") { + return "_${w}"; + } elsif ($wtype eq "ee") { + return "${w}_"; + } elsif ($wtype eq "eo") { + return "_${w}_"; + } elsif ($wmajt eq "x" || $wmajt eq "i") { + return "\001"; + } else { + die "panic in word_txt: $wtype$w\n"; + } +} + +sub write_html { + # This is called from the top level, so I won't bother using + # my or local. + + # Write contents file. Just the preamble, then a menu of links to the + # separate chapter files and the nodes therein. + print "writing contents file..."; + open TEXT,">nasmdoc0.html"; + select TEXT; + &html_preamble(0); + print "<p>This manual documents NASM, the Netwide Assembler: an assembler\n"; + print "targetting the Intel x86 series of processors, with portable source.\n"; + print "<p>"; + for ($node = $tstruct_next{'Top'}; $node; $node = $tstruct_next{$node}) { + if ($tstruct_level{$node} == 1) { + # Invent a file name. + ($number = lc($xrefnodes{$node})) =~ s/.*-//; + $fname="nasmdocx.html"; + substr($fname,8 - length $number, length $number) = $number; + $html_fnames{$node} = $fname; + $link = $fname; + print "<p>"; + } else { + # Use the preceding filename plus a marker point. + $link = $fname . "#$xrefnodes{$node}"; + } + $title = "$node: "; + $pname = $tstruct_pname{$node}; + foreach $i (@$pname) { + $ww = &word_html($i); + $title .= $ww unless $ww eq "\001"; + } + print "<a href=\"$link\">$title</a><br>\n"; + } + print "<p><a href=\"nasmdoci.html\">Index</a>\n"; + print "</body></html>\n"; + select STDOUT; + close TEXT; + + # Open a null file, to ensure output (eg random &html_jumppoints calls) + # goes _somewhere_. + print "writing chapter files..."; + open TEXT,">/dev/null"; + select TEXT; + $html_lastf = ''; + + $in_list = 0; + + for ($para = 0; $para <= $#pnames; $para++) { + $pname = $pnames[$para]; + $pflags = $pflags[$para]; + $ptype = substr($pflags,0,4); + + $in_list = 0, print "</ul>\n" if $in_list && $ptype ne "bull"; + if ($ptype eq "chap") { + # Chapter heading. Begin a new file. + $pflags =~ /chap (.*) :(.*)/; + $title = "Chapter $1: "; + $xref = $2; + &html_jumppoints; print "</body></html>\n"; select STDOUT; close TEXT; + $html_lastf = $html_fnames{$chapternode}; + $chapternode = $nodexrefs{$xref}; + $html_nextf = $html_fnames{$tstruct_mnext{$chapternode}}; + open TEXT,">$html_fnames{$chapternode}"; select TEXT; &html_preamble(1); + foreach $i (@$pname) { + $ww = &word_html($i); + $title .= $ww unless $ww eq "\001"; + } + $h = "<h2><a name=\"$xref\">$title</a></h2>\n"; + print $h; print FULL $h; + } elsif ($ptype eq "appn") { + # Appendix heading. Begin a new file. + $pflags =~ /appn (.*) :(.*)/; + $title = "Appendix $1: "; + $xref = $2; + &html_jumppoints; print "</body></html>\n"; select STDOUT; close TEXT; + $html_lastf = $html_fnames{$chapternode}; + $chapternode = $nodexrefs{$xref}; + $html_nextf = $html_fnames{$tstruct_mnext{$chapternode}}; + open TEXT,">$html_fnames{$chapternode}"; select TEXT; &html_preamble(1); + foreach $i (@$pname) { + $ww = &word_html($i); + $title .= $ww unless $ww eq "\001"; + } + print "<h2><a name=\"$xref\">$title</a></h2>\n"; + } elsif ($ptype eq "head" || $ptype eq "subh") { + # Heading or subheading. + $pflags =~ /.... (.*) :(.*)/; + $hdr = ($ptype eq "subh" ? "h4" : "h3"); + $title = $1 . " "; + $xref = $2; + foreach $i (@$pname) { + $ww = &word_html($i); + $title .= $ww unless $ww eq "\001"; + } + print "<$hdr><a name=\"$xref\">$title</a></$hdr>\n"; + } elsif ($ptype eq "code") { + # Code paragraph. + print "<p><pre>\n"; + foreach $i (@$pname) { + $w = $i; + $w =~ s/&/&/g; + $w =~ s/</</g; + $w =~ s/>/>/g; + print $w, "\n"; + } + print "</pre>\n"; + } elsif ($ptype eq "bull" || $ptype eq "norm") { + # Ordinary paragraph, optionally bulleted. We wrap, with ragged + # 75-char right margin and either 7 or 11 char left margin + # depending on bullets. + if ($ptype eq "bull") { + $in_list = 1, print "<ul>\n" unless $in_list; + $line = '<li>'; + } else { + $line = '<p>'; + } + @a = @$pname; + $wd = $wprev = ''; + do { + do { $w = &word_html(shift @a) } while $w eq "\001"; # nasty hack + $wd .= $wprev; + if ($w eq ' ' || $w eq '' || $w eq undef) { + if (length ($line . $wd) > 75) { + $line =~ s/\s*$//; # trim trailing spaces + print "$line\n"; + $line = ''; + $wd =~ s/^\s*//; # trim leading spaces + } + $line .= $wd; + $wd = ''; + } + $wprev = $w; + } while ($w ne '' && $w ne undef); + if ($line =~ /\S/) { + $line =~ s/\s*$//; # trim trailing spaces + print "$line\n"; + } + } + } + + # Close whichever file was open. + &html_jumppoints; + print "</body></html>\n"; + select STDOUT; + close TEXT; + + print "\n writing index file..."; + open TEXT,">nasmdoci.html"; + select TEXT; + &html_preamble(0); + print "<p align=center><a href=\"nasmdoc0.html\">Contents</a>\n"; + print "<p>"; + &html_index; + print "<p align=center><a href=\"nasmdoc0.html\">Contents</a>\n"; + print "</body></html>\n"; + select STDOUT; + close TEXT; +} + +sub html_preamble { + print "<html><head><title>NASM Manual</title></head>\n"; + print "<body><h1 align=center>The Netwide Assembler: NASM</h1>\n\n"; + &html_jumppoints if $_[0]; +} + +sub html_jumppoints { + print "<p align=center>"; + print "<a href=\"$html_nextf\">Next Chapter</a> |\n" if $html_nextf; + print "<a href=\"$html_lastf\">Previous Chapter</a> |\n" if $html_lastf; + print "<a href=\"nasmdoc0.html\">Contents</a> |\n"; + print "<a href=\"nasmdoci.html\">Index</a>\n"; +} + +sub html_index { + my $itag, $a, @ientry, $sep, $w, $wd, $wprev, $line; + + $chapternode = ''; + foreach $itag (@itags) { + $ientry = $idxmap{$itag}; + @a = @$ientry; + push @a, "n :"; + $sep = 0; + foreach $node (@nodes) { + next if !$idxnodes{$node,$itag}; + push @a, "n ," if $sep; + push @a, "sp", "x $xrefnodes{$node}", "n $node", "xe$xrefnodes{$node}"; + $sep = 1; + } + $line = ''; + do { + do { $w = &word_html(shift @a) } while $w eq "\001"; # nasty hack + $wd .= $wprev; + if ($w eq ' ' || $w eq '' || $w eq undef) { + if (length ($line . $wd) > 75) { + $line =~ s/\s*$//; # trim trailing spaces + print "$line\n"; + $line = ''; + $wd =~ s/^\s*//; # trim leading spaces + } + $line .= $wd; + $wd = ''; + } + $wprev = $w; + } while ($w ne '' && $w ne undef); + if ($line =~ /\S/) { + $line =~ s/\s*$//; # trim trailing spaces + print "$line\n"; + } + print "<br>\n"; + } +} + +sub word_html { + my ($w) = @_; + my $wtype, $wmajt, $pfx, $sfx; + + return undef if $w eq '' || $w eq undef; + + $wtype = substr($w,0,2); + $wmajt = substr($wtype,0,1); + $w = substr($w,2); + $pfx = $sfx = ''; + $pfx = "<a href=\"$1\">", $sfx = "</a>", $w = $2 + if $wmajt eq "w" && $w =~ /^<(.*)>(.*)$/; + $w =~ s/&/&/g; + $w =~ s/</</g; + $w =~ s/>/>/g; + if ($wmajt eq "n" || $wtype eq "e " || $wtype eq "w ") { + return $pfx . $w . $sfx; + } elsif ($wtype eq "sp") { + return ' '; + } elsif ($wtype eq "da") { + return '-'; # sadly, en-dashes are non-standard in HTML + } elsif ($wmajt eq "c" || $wtype eq "wc") { + return $pfx . "<code><nobr>${w}</nobr></code>" . $sfx; + } elsif ($wtype eq "es") { + return "<em>${w}"; + } elsif ($wtype eq "ee") { + return "${w}</em>"; + } elsif ($wtype eq "eo") { + return "<em>${w}</em>"; + } elsif ($wtype eq "x ") { + # Magic: we must resolve the cross reference into file and marker + # parts, then dispose of the file part if it's us, and dispose of + # the marker part if the cross reference describes the top node of + # another file. + my $node = $nodexrefs{$w}; # find the node we're aiming at + my $level = $tstruct_level{$node}; # and its level + my $up = $node, $uplev = $level-1; + $up = $tstruct_up{$up} while $uplev--; # get top node of containing file + my $file = ($up ne $chapternode) ? $html_fnames{$up} : ""; + my $marker = ($level == 1 and $file) ? "" : "#$w"; + return "<a href=\"$file$marker\">"; + } elsif ($wtype eq "xe") { + return "</a>"; + } elsif ($wmajt eq "i") { + return "\001"; + } else { + die "panic in word_html: $wtype$w\n"; + } +} + +sub write_ps { + # This is called from the top level, so I won't bother using + # my or local. + + # First, set up the font metric arrays. + &font_metrics; + + # First stage: reprocess the source arrays into a list of + # lines, each of which is a list of word-strings, each of + # which has a single-letter font code followed by text. + # Each line also has an associated type, which will be + # used for final alignment and font selection and things. + # + # Font codes are: + # n == Normal + # e == Emphasised + # c == Code + # ' ' == space (no following text required) + # '-' == dash (no following text required) + # + # Line types are: + # chap == Chapter or appendix heading. + # head == Major heading. + # subh == Sub-heading. + # Ccha == Contents entry for a chapter. + # Chea == Contents entry for a heading. + # Csub == Contents entry for a subheading. + # cone == Code paragraph with just this one line on it. + # cbeg == First line of multi-line code paragraph. + # cbdy == Interior line of multi-line code paragraph. + # cend == Final line of multi-line code paragraph. + # none == Normal paragraph with just this one line on it. + # nbeg == First line of multi-line normal paragraph. + # nbdy == Interior line of multi-line normal paragraph. + # nend == Final line of multi-line normal paragraph. + # bone == Bulleted paragraph with just this one line on it. + # bbeg == First line of multi-line bulleted paragraph. + # bbdy == Interior line of multi-line bulleted paragraph. + # bend == Final line of multi-line bulleted paragraph. + print "line-breaks..."; + $lname = "psline000000"; + $lnamei = "idx" . $lname; + @lnames = @ltypes = (); + + for ($para = 0; $para <= $#pnames; $para++) { + $pname = $pnames[$para]; + $pflags = $pflags[$para]; + $ptype = substr($pflags,0,4); + + # New paragraph _ergo_ new line. + @line = (); + @lindex = (); # list of index tags referenced to this line + + if ($ptype eq "chap") { + # Chapter heading. "Chapter N: Title" followed by a line of + # minus signs. + $pflags =~ /chap (.*) :(.*)/; + push @line, "nChapter", " ", "n$1:", " "; + foreach $i (@$pname) { + $ww = &word_ps($i); + push @line, $ww unless $ww eq "x"; + } + @$lname = @line; @$lnamei = @lindex; + push @lnames, $lname++; + $lnamei = "idx" . $lname; + push @ltypes, "chap"; + } elsif ($ptype eq "appn") { + # Appendix heading. "Appendix N: Title" followed by a line of + # minus signs. + $pflags =~ /appn (.*) :(.*)/; + push @line, "nAppendix", " ", "n$1:", " "; + foreach $i (@$pname) { + $ww = &word_ps($i); + push @line, $ww unless $ww eq "x"; + } + @$lname = @line; @$lnamei = @lindex; + push @lnames, $lname++; + $lnamei = "idx" . $lname; + push @ltypes, "chap"; + } elsif ($ptype eq "head") { + # Heading. Just a number and some text. + $pflags =~ /.... (.*) :(.*)/; + push @line, "n$1"; + foreach $i (@$pname) { + $ww = &word_ps($i); + push @line, $ww unless $ww eq "x"; + } + @$lname = @line; @$lnamei = @lindex; + push @lnames, $lname++; + $lnamei = "idx" . $lname; + push @ltypes, $ptype; + } elsif ($ptype eq "subh") { + # Subheading. Just a number and some text. + $pflags =~ /subh (.*) :(.*)/; + push @line, "n$1"; + foreach $i (@$pname) { + push @line, &word_ps($i); + } + @$lname = @line; @$lnamei = @lindex; + push @lnames, $lname++; + $lnamei = "idx" . $lname; + push @ltypes, "subh"; + } elsif ($ptype eq "code") { + # Code paragraph. Emit lines one at a time. + $type = "cbeg"; + foreach $i (@$pname) { + @$lname = ("c$i"); + push @lnames, $lname++; + $lnamei = "idx" . $lname; + push @ltypes, $type; + $type = "cbdy"; + } + $ltypes[$#ltypes] = ($ltypes[$#ltypes] eq "cbeg" ? "cone" : "cend"); + } elsif ($ptype eq "bull" || $ptype eq "norm") { + # Ordinary paragraph, optionally bulleted. We wrap, with ragged + # 75-char right margin and either 7 or 11 char left margin + # depending on bullets. + if ($ptype eq "bull") { + $width = 456; # leave 12-pt left indent for the bullet + $type = $begtype = "bbeg"; + $bodytype = "bbdy"; + $onetype = "bone"; + $endtype = "bend"; + } else { + $width = 468; + $type = $begtype = "nbeg"; + $bodytype = "nbdy"; + $onetype = "none"; + $endtype = "nend"; + } + @a = @$pname; + @line = @wd = (); + $linelen = 0; + $wprev = undef; + do { + do { $w = &word_ps(shift @a) } while ($w eq "x"); + push @wd, $wprev if $wprev; + if ($wprev =~ /^n.*-$/ || $w eq ' ' || $w eq '' || $w eq undef) { + $wdlen = &len_ps(@wd); + if ($linelen + $wdlen > $width) { + pop @line while $line[$#line] eq ' '; # trim trailing spaces + @$lname = @line; @$lnamei = @lindex; + push @lnames, $lname++; + $lnamei = "idx" . $lname; + push @ltypes, $type; + $type = $bodytype; + @line = @lindex = (); + $linelen = 0; + shift @wd while $wd[0] eq ' '; # trim leading spaces + } + push @line, @wd; + $linelen += $wdlen; + @wd = (); + } + $wprev = $w; + } while ($w ne '' && $w ne undef); + if (@line) { + pop @line while $line[$#line] eq ' '; # trim trailing spaces + @$lname = @line; @$lnamei = @lindex; + push @lnames, $lname++; + $lnamei = "idx" . $lname; + push @ltypes, $type; + $type = $bodytype; + } + $ltypes[$#ltypes] = + ($ltypes[$#ltypes] eq $begtype ? $onetype : $endtype); + } + } + + # We've now processed the document source into lines. Before we + # go on and do the page breaking, we'll fabricate a table of contents, + # line by line, and then after doing page breaks we'll go back and + # insert the page numbers into the contents entries. + print "building contents..."; + @clnames = @cltypes = (); + $clname = "pscont000000"; + @$clname = ("nContents"); # "chapter heading" for TOC + push @clnames,$clname++; + push @cltypes,"chap"; + for ($i=0; $i<=$#lnames; $i++) { + $lname = $lnames[$i]; + if ($ltypes[$i] =~ /^(chap|head|subh)/) { + @$clname = @$lname; + splice @$clname,1,0," " if ($ltypes[$i] !~ /chap/); + push @$clname,$i; # placeholder for page number + push @clnames,$clname++; + push @cltypes,"C" . substr($ltypes[$i],0,3); + } + } + @$clname = ("nIndex"); # contents entry for Index + push @$clname,$i; # placeholder for page number + $idx_clname = $clname; + push @clnames,$clname++; + push @cltypes,"Ccha"; + $contlen = $#clnames + 1; + unshift @lnames,@clnames; + unshift @ltypes,@cltypes; + + # Second stage: now we have a list of lines, break them into pages. + # We do this by means of adding a third array in parallel with + # @lnames and @ltypes, called @lpages, in which we store the page + # number that each line resides on. We also add @ycoord which + # stores the vertical position of each line on the page. + # + # Page breaks may not come after line-types: + # chap head subh cbeg nbeg bbeg + # and may not come before line-types: + # cend nend bend + # They are forced before line-types: + # chap + print "page-breaks..."; + $pmax = 600; # ADJUSTABLE: maximum length of a page in points + $textht = 11; # ADJUSTABLE: height of a normal line in points + $spacing = 6; # ADJUSTABLE: space between paragraphs, in points + $headht = 14; # ADJUSTABLE: height of a major heading in points + $subht = 12; # ADJUSTABLE: height of a sub-heading in points + $pstart = 0; # start line of current page + $plen = 0; # current length of current page + $pnum = 1; # number of current page + $bpt = -1; # last feasible break point + $i = 0; # line number + while ($i <= $#lnames) { + $lname = $lnames[$i]; + # Add the height of this line (computed the last time we went round + # the loop, unless we're a chapter heading in which case we do it + # now) to the length of the current page. Also, _put_ this line on + # the current page, and allocate it a y-coordinate. + if ($ltypes[$i] =~ /^chap$/) { + $plen = 100; # ADJUSTABLE: space taken up by a chapter heading + $ycoord[$i] = 0; # chapter heading: y-coord doesn't matter + } else { + $ycoord[$i] = $plen + $space; + $plen += $space + $ht; + } + # See if we can break after this line. + $bpt = $i if $ltypes[$i] !~ /^chap|head|subh|cbeg|nbeg|bbeg$/ && + $ltypes[$i+1] !~ /^cend|nend|bend$/; + # Assume, to start with, that we don't break after this line. + $break = 0; + # See if a break is forced. + $break = 1, $bpt = $i if $ltypes[$i+1] eq "chap" || !$ltypes[$i+1]; + # Otherwise, compute the height of the next line, and break if + # it would make this page too long. + $ht = $textht, $space = 0 if $ltypes[$i+1] =~ /^[nbc](bdy|end)$/; + $ht = $textht, $space = $spacing if $ltypes[$i+1] =~ /^[nbc](one|beg)$/; + $ht = $textht, $space = $spacing if $ltypes[$i+1] =~ /^C/; + $ht = $subht, $space = $spacing if $ltypes[$i+1] eq "subh"; + $ht = $headht, $space = $spacing if $ltypes[$i+1] eq "head"; + $break = 1 if $plen + $space + $ht > $pmax; + # Now, if we're breaking, assign page number $pnum to all lines up + # to $bpt, set $i == $bpt+1, and zero $space since we are at the + # start of a new page and don't want leading space. + if ($break) { + die "no feasible break point at all on page $pnum\n" if $bpt == -1; + for ($j = $pstart; $j <= $bpt; $j++) { + $lnamei = "idx" . $lnames[$j]; + foreach $k (@$lnamei) { + ${$psidxpp{$k}}{$pnum} = 1; + } + $lpages[$j] = $pnum; + } + $pnum++; + $i = $bpt; + $bpt = -1; + $pstart = $i+1; + $plen = 0; + $space = 0; + } + $i++; + } + + # Now fix up the TOC with page numbers. + print "\n fixing up contents..."; + for ($i=0; $i<=$#lnames; $i++) { + $lname = $lnames[$i]; + if ($ltypes[$i] =~ /^C/) { + $j = pop @$lname; + push @$lname, "n" . $lpages[$j+$contlen]; + } + } + + # Having got page numbers for most stuff, generate an index. + print "building index..."; + $iwid = 222; + $sep = 12; + $commaindent = 32; + foreach $k (@itags) { + @line = (); + $cmd = "index"; + @idxentry = @{$idxmap{$k}}; + if ($commaafter{$k} and !$commanext{$k}) { + # This line is a null line beginning a multiple entry. We must + # output the prefix on a line by itself. + + @idxhead = splice @idxentry,0,$commapos{$k}; + @line = (); + foreach $i (@idxhead) { + $ww = &word_ps($i); + push @line, $ww unless $ww eq "x"; + } + &ps_idxout("index",\@line,[]); + $cmd = "iindex"; + @line = (); + } + $cmd = "iindex", splice @idxentry,0,$commapos{$k} if $commanext{$k}; + foreach $i (@idxentry) { + $ww = &word_ps($i); + push @line, $ww unless $ww eq "x"; + } + $len = $iwid - $sep - &len_ps(@line); + warn "text for index tag `%s' is longer than one index line!\n" + if $len < -$sep; + @pp = (); + $inums = join(',',sort { $a <=> $b } keys %{$psidxpp{$k}}); + while (length $inums) { + $inums =~ /^([^,]+,?)(.*)$/; + $inums = $2, $inum = $1; + @pnum = (" ", "n$inum"); + $pnumlen = &len_ps(@pnum); + if ($pnumlen > $len) { + &ps_idxout($cmd,\@line,\@pp); + @pp = (); + @line = (); + $cmd = "index"; + $len = $iwid - $sep; + } + push @pp, @pnum; + $len -= $pnumlen; + } + &ps_idxout($cmd,\@line,\@pp) if (length @pp); + $l1 = &len_ps(@line); + $l2 = &len_ps($pp); + } + $$idx_clname[$#$idx_clname] = "n" . $pnum; # fix up TOC entry for index + + print "writing file..."; + open PS,">nasmdoc.ps"; + select PS; + $page = $lpages[0]; + &ps_header; + for ($i=0; $i<=$#lnames; $i++) { + &ps_throw_pg($page,$lpages[$i]) if $page != $lpages[$i]; + $page = $lpages[$i]; + &ps_out_line($ycoord[$i],$ltypes[$i],$lnames[$i]); + } + $i = 0; + while ($i <= $#psindex) { + &ps_throw_pg($page, $pnum) if $page != $pnum; + $page = $pnum++; + $ypos = 0; + $ypos = 100, &ps_out_line(0, "chap", ["nIndex"]) if !$i; + $lines = ($pmax - $ypos) / $textht; + my $col; # ps_out_line hits this variable + PAGE:for ($col = 1; $col <= 2; $col++) { + $y = $ypos; $l = $lines; + COL: while ($l > 0) { + $j = $i+1; + $j++ while $psindex[$j] and ($psindex[$j][3] == 0); # find next break + last COL if $j-$i > $l or $i > $#psindex; + while ($i < $j) { + &ps_out_line($y, $psindex[$i][0] eq "index" ? "idl$col" : "ldl$col", + $psindex[$i][1]); + &ps_out_line($y,"idr$col",$psindex[$i][2]); + $i++; + $y += $textht; + $l--; + } + } + last PAGE if $i > $#psindex; + } + } + &ps_trailer; + close PS; + select STDOUT; +} + +sub ps_idxout { + my ($cmd, $left, $right) = @_; + my $break = 1; + $break = 0 + if ($#psindex >= 0) and ( ($#$left < 0) or ($cmd eq "iindex") ); + push @psindex,[$cmd,[@$left],[@$right],$break]; +} + +sub ps_header { + @pshdr = ( + '/sp (n ) def', # here it's sure not to get wrapped inside () + '/nf /Times-Roman findfont 11 scalefont def', + '/ef /Times-Italic findfont 11 scalefont def', + '/cf /Courier findfont 11 scalefont def', + '/nc /Helvetica-Bold findfont 18 scalefont def', + '/ec /Helvetica-Oblique findfont 18 scalefont def', + '/cc /Courier-Bold findfont 18 scalefont def', + '/nh /Helvetica-Bold findfont 14 scalefont def', + '/eh /Helvetica-Oblique findfont 14 scalefont def', + '/ch /Courier-Bold findfont 14 scalefont def', + '/ns /Helvetica-Bold findfont 12 scalefont def', + '/es /Helvetica-Oblique findfont 12 scalefont def', + '/cs /Courier-Bold findfont 12 scalefont def', + '/n 16#6E def /e 16#65 def /c 16#63 def', + '/chapter {', + ' 100 620 moveto', + ' {', + ' dup 0 get', + ' dup n eq {pop nc setfont} {', + ' e eq {ec setfont} {cc setfont} ifelse', + ' } ifelse', + ' dup length 1 sub 1 exch getinterval show', + ' } forall', + ' 0 setlinecap 3 setlinewidth', + ' newpath 100 610 moveto 468 0 rlineto stroke', + '} def', + '/heading {', + ' 686 exch sub /y exch def /a exch def', + ' 90 y moveto a 0 get dup length 1 sub 1 exch getinterval', + ' nh setfont dup stringwidth pop neg 0 rmoveto show', + ' 100 y moveto', + ' a dup length 1 sub 1 exch getinterval {', + ' /s exch def', + ' s 0 get', + ' dup n eq {pop nh setfont} {', + ' e eq {eh setfont} {ch setfont} ifelse', + ' } ifelse', + ' s s length 1 sub 1 exch getinterval show', + ' } forall', + '} def', + '/subhead {', + ' 688 exch sub /y exch def /a exch def', + ' 90 y moveto a 0 get dup length 1 sub 1 exch getinterval', + ' ns setfont dup stringwidth pop neg 0 rmoveto show', + ' 100 y moveto', + ' a dup length 1 sub 1 exch getinterval {', + ' /s exch def', + ' s 0 get', + ' dup n eq {pop ns setfont} {', + ' e eq {es setfont} {cs setfont} ifelse', + ' } ifelse', + ' s s length 1 sub 1 exch getinterval show', + ' } forall', + '} def', + '/disp { /j exch def', + ' 568 exch sub exch 689 exch sub moveto', + ' {', + ' /s exch def', + ' s 0 get', + ' dup n eq {pop nf setfont} {', + ' e eq {ef setfont} {cf setfont} ifelse', + ' } ifelse', + ' s s length 1 sub 1 exch getinterval show', + ' s sp eq {j 0 rmoveto} if', + ' } forall', + '} def', + '/contents { /w exch def /y exch def /a exch def', + ' /yy 689 y sub def', + ' a a length 1 sub get dup length 1 sub 1 exch getinterval /s exch def', + ' nf setfont 568 s stringwidth pop sub /ex exch def', + ' ex yy moveto s show', + ' a 0 a length 1 sub getinterval y w 0 disp', + ' /sx currentpoint pop def nf setfont', + ' 100 10 568 { /i exch def', + ' i 5 sub sx gt i 5 add ex lt and {', + ' i yy moveto (.) show', + ' } if', + ' } for', + '} def', + '/just { /w exch def /y exch def /a exch def', + ' /jj w def /spaces 0 def', + ' a {', + ' /s exch def', + ' s 0 get', + ' dup n eq {pop nf setfont} {', + ' e eq {ef setfont} {cf setfont} ifelse', + ' } ifelse', + ' s s length 1 sub 1 exch getinterval stringwidth pop', + ' jj exch sub /jj exch def', + ' s sp eq {/spaces spaces 1 add def} if', + ' } forall', + ' a y w jj spaces spaces 0 eq {pop pop 0} {div} ifelse disp', + '} def', + '/idl { 468 exch sub 0 disp } def', + '/ldl { 436 exch sub 0 disp } def', + '/idr { 222 add 468 exch sub /x exch def /y exch def /a exch def', + ' a {', + ' /s exch def', + ' s 0 get', + ' dup n eq {pop nf setfont} {', + ' e eq {ef setfont} {cf setfont} ifelse', + ' } ifelse', + ' s s length 1 sub 1 exch getinterval stringwidth pop', + ' x add /x exch def', + ' } forall', + ' a y x 0 disp', + '} def', + '/left {0 disp} def', + '/bullet {', + ' nf setfont dup 100 exch 689 exch sub moveto (\267) show', + '} def' + ); + print "%!PS-Adobe-3.0\n"; + print "%%BoundingBox: 95 95 590 705\n"; + print "%%Creator: a nasty Perl script\n"; + print "%%DocumentData: Clean7Bit\n"; + print "%%Orientation: Portrait\n"; + print "%%Pages: $lpages[$#lpages]\n"; + print "%%DocumentNeededResources: font Times-Roman Times-Italic\n"; + print "%%+ font Helvetica-Bold Courier Courier-Bold\n"; + print "%%EndComments\n%%BeginProlog\n%%EndProlog\n%%BeginSetup\nsave\n"; + $pshdr = join(' ',@pshdr); + $pshdr =~ s/\s+/ /g; + while ($pshdr =~ /\S/) { + last if length($pshdr) < 72 || $pshdr !~ /^(.{0,72}\S)\s(.*)$/; + $pshdr = $2; + print "$1\n"; + } + print "$pshdr\n" if $pshdr =~ /\S/; + print "%%EndSetup\n"; + &ps_initpg($lpages[0]); +} + +sub ps_trailer { + &ps_donepg; + print "%%Trailer\nrestore\n%%EOF\n"; +} + +sub ps_throw_pg { + my ($oldpg, $newpg) = @_; + &ps_donepg; + &ps_initpg($newpg); +} + +sub ps_initpg { + my ($pgnum) = @_; + print "%%Page: $pgnum $pgnum\n"; + print "%%BeginPageSetup\nsave\n%%EndPageSetup\n"; +} + +sub ps_donepg { + print "%%PageTrailer\nrestore showpage\n"; +} + +sub ps_out_line { + my ($ypos,$ltype,$lname) = @_; + my $c,$d,$wid; + + print "["; + $col = 1; + foreach $c (@$lname) {# + $c= "n " if $c eq " "; + $c = "n\261" if $c eq "-"; + $d = ''; + while (length $c) { + $d .= $1, $c = $2 while $c =~ /^([ -'\*-\[\]-~]+)(.*)$/; + while (1) { + $d .= "\\$1", $c = $2, next if $c =~ /^([\\\(\)])(.*)$/; + ($d .= sprintf "\\%3o",unpack("C",$1)), $c = $2, next + if $c =~ /^([^ -~])(.*)$/; + last; + } + } + $d = "($d)"; + $col = 0, print "\n" if $col>0 && $col+length $d > 77; + print $d; + $col += length $d; + } + print "\n" if $col > 60; + print "]"; + if ($ltype =~ /^[nb](beg|bdy)$/) { + printf "%d %s%d just\n", + $ypos, ($ltype eq "bbeg" ? "bullet " : ""), + ($ltype =~ /^b/ ? 456 : 468); + } elsif ($ltype =~ /^[nb](one|end)$/) { + printf "%d %s%d left\n", + $ypos, ($ltype eq "bone" ? "bullet " : ""), + ($ltype =~ /^b/ ? 456 : 468); + } elsif ($ltype =~ /^c(one|beg|bdy|end)$/) { + printf "$ypos 468 left\n"; + } elsif ($ltype =~ /^C/) { + $wid = 468; + $wid = 456 if $ltype eq "Chea"; + $wid = 444 if $ltype eq "Csub"; + printf "$ypos $wid contents\n"; + } elsif ($ltype eq "chap") { + printf "chapter\n"; + } elsif ($ltype eq "head") { + printf "$ypos heading\n"; + } elsif ($ltype eq "subh") { + printf "$ypos subhead\n"; + } elsif ($ltype =~ /([il]d[lr])([12])/) { + $left = ($2 eq "2" ? 468-222 : 0); + printf "$ypos $left $1\n"; + } +} + +sub word_ps { + my ($w) = @_; + my $wtype, $wmajt; + + return undef if $w eq '' || $w eq undef; + + $wtype = substr($w,0,2); + $wmajt = substr($wtype,0,1); + $w = substr($w,2); + $w =~ s/<.*>// if $wmajt eq "w"; # remove web links + if ($wmajt eq "n" || $wtype eq "w ") { + return "n$w"; + } elsif ($wtype eq "sp") { + return ' '; + } elsif ($wtype eq "da") { + return '-'; + } elsif ($wmajt eq "c" || $wtype eq "wc") { + return "c$w"; + } elsif ($wmajt eq "e") { + return "e$w"; + } elsif ($wmajt eq "x") { + return "x"; + } elsif ($wtype eq "i ") { + push @lindex, $w; + return "x"; + } else { + die "panic in word_ps: $wtype$w\n"; + } +} + +sub len_ps { + my (@line) = @_; + my $l = 0; + my $w, $size; + + $size = 11/1000; # used only for length calculations + while ($w = shift @line) { + $w = "n " if $w eq " "; + $w = "n\261" if $w eq "-"; + $f = substr($w,0,1); + $f = "timesr" if $f eq "n"; + $f = "timesi" if $f eq "e"; + $f = "courr" if $f eq "c"; + foreach $c (unpack 'C*',substr($w,1)) { + $l += $size * $$f[$c]; + } + } + return $l; +} + +sub write_texi { + # This is called from the top level, so I won't bother using + # my or local. + + # Open file. + print "writing file..."; + open TEXT,">nasmdoc.texi"; + select TEXT; + + # Preamble. + print "\input texinfo \@c -*-texinfo-*-\n"; + print "\@c \%**start of header\n"; + print "\@setfilename nasm.info\n"; + print "\@settitle NASM: The Netwide Assembler\n"; + print "\@setchapternewpage odd\n"; + print "\@c \%**end of header\n"; + print "\n"; + print "\@ifinfo\n"; + print "This file documents NASM, the Netwide Assembler: an assembler\n"; + print "targetting the Intel x86 series of processors, with portable source.\n"; + print "\n"; + print "Copyright 1997 Simon Tatham\n"; + print "\n"; + print "All rights reserved. This document is redistributable under the\n"; + print "licence given in the file \"Licence\" distributed in the NASM archive.\n"; + print "\@end ifinfo\n"; + print "\n"; + print "\@titlepage\n"; + print "\@title NASM: The Netwide Assembler\n"; + print "\@author Simon Tatham\n"; + print "\n"; + print "\@page\n"; + print "\@vskip 0pt plus 1filll\n"; + print "Copyright \@copyright{} 1997 Simon Tatham\n"; + print "\n"; + print "All rights reserved. This document is redistributable under the\n"; + print "licence given in the file \"Licence\" distributed in the NASM archive.\n"; + print "\@end titlepage\n"; + print "\n"; + print "\@node Top, $tstruct_next{'Top'}, (dir), (dir)\n"; + print "\@top\n"; + print "\n"; + print "\@ifinfo\n"; + print "This file documents NASM, the Netwide Assembler: an assembler\n"; + print "targetting the Intel x86 series of processors, with portable source.\n"; + print "\@end ifinfo\n"; + + $node = "Top"; + + $bulleting = 0; + for ($para = 0; $para <= $#pnames; $para++) { + $pname = $pnames[$para]; + $pflags = $pflags[$para]; + $ptype = substr($pflags,0,4); + + $bulleting = 0, print "\@end itemize\n" if $bulleting && $ptype ne "bull"; + print "\n"; # always one of these before a new paragraph + + if ($ptype eq "chap") { + # Chapter heading. Begin a new node. + &texi_menu($node) + if $tstruct_level{$tstruct_next{$node}} > $tstruct_level{$node}; + $pflags =~ /chap (.*) :(.*)/; + $node = "Chapter $1"; + $title = "Chapter $1: "; + foreach $i (@$pname) { + $ww = &word_texi($i); + $title .= $ww unless $ww eq "\001"; + } + print "\@node $node, $tstruct_next{$node}, $tstruct_prev{$node},"; + print " $tstruct_up{$node}\n\@unnumbered $title\n"; + } elsif ($ptype eq "appn") { + # Appendix heading. Begin a new node. + &texi_menu($node) + if $tstruct_level{$tstruct_next{$node}} > $tstruct_level{$node}; + $pflags =~ /appn (.*) :(.*)/; + $node = "Appendix $1"; + $title = "Appendix $1: "; + foreach $i (@$pname) { + $ww = &word_texi($i); + $title .= $ww unless $ww eq "\001"; + } + print "\@node $node, $tstruct_next{$node}, $tstruct_prev{$node},"; + print " $tstruct_up{$node}\n\@unnumbered $title\n"; + } elsif ($ptype eq "head" || $ptype eq "subh") { + # Heading or subheading. Begin a new node. + &texi_menu($node) + if $tstruct_level{$tstruct_next{$node}} > $tstruct_level{$node}; + $pflags =~ /.... (.*) :(.*)/; + $node = "Section $1"; + $title = "$1. "; + foreach $i (@$pname) { + $ww = &word_texi($i); + $title .= $ww unless $ww eq "\001"; + } + print "\@node $node, $tstruct_next{$node}, $tstruct_prev{$node},"; + print " $tstruct_up{$node}\n\@unnumbered $title\n"; + } elsif ($ptype eq "code") { + # Code paragraph. Surround with @example / @end example. + print "\@example\n"; + foreach $i (@$pname) { + warn "code line longer than 68 chars: $i\n" if length $i > 68; + $i =~ s/\@/\@\@/g; + $i =~ s/\{/\@\{/g; + $i =~ s/\}/\@\}/g; + print "$i\n"; + } + print "\@end example\n"; + } elsif ($ptype eq "bull" || $ptype eq "norm") { + # Ordinary paragraph, optionally bulleted. We wrap, FWIW. + if ($ptype eq "bull") { + $bulleting = 1, print "\@itemize \@bullet\n" if !$bulleting; + print "\@item\n"; + } + $line = ''; + @a = @$pname; + $wd = $wprev = ''; + do { + do { $w = &word_texi(shift @a); } while $w eq "\001"; # hack + $wd .= $wprev; + if ($wprev =~ /-$/ || $w eq ' ' || $w eq '' || $w eq undef) { + if (length ($line . $wd) > 75) { + $line =~ s/\s*$//; # trim trailing spaces + print "$line\n"; + $line = ''; + $wd =~ s/^\s*//; # trim leading spaces + } + $line .= $wd; + $wd = ''; + } + $wprev = $w; + } while ($w ne '' && $w ne undef); + if ($line =~ /\S/) { + $line =~ s/\s*$//; # trim trailing spaces + print "$line\n"; + } + } + } + + # Write index. + &texi_index; + + # Close file. + print "\n\@contents\n\@bye\n"; + select STDOUT; + close TEXT; +} + +# Side effect of this procedure: update global `texiwdlen' to be the length +# in chars of the formatted version of the word. +sub word_texi { + my ($w) = @_; + my $wtype, $wmajt; + + return undef if $w eq '' || $w eq undef; + $wtype = substr($w,0,2); + $wmajt = substr($wtype,0,1); + $w = substr($w,2); + $wlen = length $w; + $w =~ s/\@/\@\@/g; + $w =~ s/\{/\@\{/g; + $w =~ s/\}/\@\}/g; + $w =~ s/<.*>// if $wmajt eq "w"; # remove web links + substr($w,0,1) =~ tr/a-z/A-Z/, $capital = 0 if $capital; + if ($wmajt eq "n" || $wtype eq "e " || $wtype eq "w ") { + $texiwdlen = $wlen; + return $w; + } elsif ($wtype eq "sp") { + $texiwdlen = 1; + return ' '; + } elsif ($wtype eq "da") { + $texiwdlen = 2; + return '--'; + } elsif ($wmajt eq "c" || $wtype eq "wc") { + $texiwdlen = 2 + $wlen; + return "\@code\{$w\}"; + } elsif ($wtype eq "es") { + $texiwdlen = 1 + $wlen; + return "\@emph\{${w}"; + } elsif ($wtype eq "ee") { + $texiwdlen = 1 + $wlen; + return "${w}\}"; + } elsif ($wtype eq "eo") { + $texiwdlen = 2 + $wlen; + return "\@emph\{${w}\}"; + } elsif ($wtype eq "x ") { + $texiwdlen = 0; # we don't need it in this case + $capital = 1; # hack + return "\@ref\{"; + } elsif ($wtype eq "xe") { + $texiwdlen = 0; # we don't need it in this case + return "\}"; + } elsif ($wmajt eq "i") { + $texiwdlen = 0; # we don't need it in this case + return "\001"; + } else { + die "panic in word_texi: $wtype$w\n"; + } +} + +sub texi_menu { + my ($topitem) = @_; + my $item, $i, $mpname, $title, $wd; + + $item = $tstruct_next{$topitem}; + print "\@menu\n"; + while ($item) { + $title = ""; + $mpname = $tstruct_pname{$item}; + foreach $i (@$mpname) { + $wd = &word_texi($i); + $title .= $wd unless $wd eq "\001"; + } + print "* ${item}:: $title\n"; + $item = $tstruct_mnext{$item}; + } + print "* Index::\n" if $topitem eq "Top"; + print "\@end menu\n"; +} + +sub texi_index { + my $itag, $ientry, @a, $wd, $item, $len; + my $subnums = "123456789ABCDEFGHIJKLMNOPQRSTU" . + "VWXYZabcdefghijklmnopqrstuvwxyz"; + + print "\@ifinfo\n\@node Index, , $FIXMElastnode, Top\n"; + print "\@unnumbered Index\n\n\@menu\n"; + + foreach $itag (@itags) { + $ientry = $idxmap{$itag}; + @a = @$ientry; + $item = ''; + $len = 0; + foreach $i (@a) { + $wd = &word_texi($i); + $item .= $wd, $len += $texiwdlen unless $wd eq "\001"; + } + $i = 0; + foreach $node (@nodes) { + next if !$idxnodes{$node,$itag}; + printf "* %s%s (%s): %s.\n", + $item, " " x (40-$len), substr($subnums,$i++,1), $node; + } + } + print "\@end menu\n\@end ifinfo\n"; +} + +sub write_hlp { + # This is called from the top level, so I won't bother using + # my or local. + + # Build the index-tag text forms. + print "building index entries..."; + @hlp_index = map { + my $i,$ww; + my $ientry = $idxmap{$_}; + my $title = ""; + foreach $i (@$ientry) { + $ww = &word_hlp($i,0); + $title .= $ww unless $ww eq "\001"; + } + $title; + } @itags; + + # Write the HPJ project-description file. + print "writing .hpj file..."; + open HPJ,">nasmdoc.hpj"; + print HPJ "[OPTIONS]\ncompress=true\n"; + print HPJ "title=NASM: The Netwide Assembler\noldkeyphrase=no\n\n"; + print HPJ "[FILES]\nnasmdoc.rtf\n\n"; + print HPJ "[CONFIG]\n"; + print HPJ 'CreateButton("btn_up", "&Up",'. + ' "JumpContents(`nasmdoc.hlp'."'".')")'; + print HPJ "\nBrowseButtons()\n"; + close HPJ; + + # Open file. + print "\n writing .rtf file..."; + open TEXT,">nasmdoc.rtf"; + select TEXT; + + # Preamble. + print "{\\rtf1\\ansi{\\fonttbl\n"; + print "\\f0\\froman Times New Roman;\\f1\\fmodern Courier New;\n"; + print "\\f2\\fswiss Arial;\\f3\\ftech Wingdings}\\deff0\n"; + print "#{\\footnote Top}\n"; + print "\${\\footnote Contents}\n"; + print "+{\\footnote browse:00000}\n"; + print "!{\\footnote DisableButton(\"btn_up\")}\n"; + print "\\keepn\\f2\\b\\fs30\\sb0\n"; + print "NASM: The Netwide Assembler\n"; + print "\\par\\pard\\plain\\sb120\n"; + print "This file documents NASM, the Netwide Assembler: an assembler \n"; + print "targetting the Intel x86 series of processors, with portable source.\n"; + + $node = "Top"; + $browse = 0; + + $newpar = "\\par\\sb120\n"; + for ($para = 0; $para <= $#pnames; $para++) { + $pname = $pnames[$para]; + $pflags = $pflags[$para]; + $ptype = substr($pflags,0,4); + + print $newpar; + $newpar = "\\par\\sb120\n"; + + if ($ptype eq "chap") { + # Chapter heading. Begin a new node. + &hlp_menu($node) + if $tstruct_level{$tstruct_next{$node}} > $tstruct_level{$node}; + $pflags =~ /chap (.*) :(.*)/; + $node = "Chapter $1"; + $title = $footnotetitle = "Chapter $1: "; + foreach $i (@$pname) { + $ww = &word_hlp($i,1); + $title .= $ww, $footnotetitle .= &word_hlp($i,0) unless $ww eq "\001"; + } + print "\\page\n"; + printf "#{\\footnote %s}\n", &hlp_sectkw($node); + print "\${\\footnote $footnotetitle}\n"; + printf "+{\\footnote browse:%05d}\n", ++$browse; + printf "!{\\footnote ChangeButtonBinding(\"btn_up\"," . + "\"JumpId(\`nasmdoc.hlp',\`%s')\");\n", + &hlp_sectkw($tstruct_up{$node}); + print "EnableButton(\"btn_up\")}\n"; + &hlp_keywords($node); + print "\\keepn\\f2\\b\\fs30\\sb60\\sa60\n"; + print "$title\n"; + $newpar = "\\par\\pard\\plain\\sb120\n"; + } elsif ($ptype eq "appn") { + # Appendix heading. Begin a new node. + &hlp_menu($node) + if $tstruct_level{$tstruct_next{$node}} > $tstruct_level{$node}; + $pflags =~ /appn (.*) :(.*)/; + $node = "Appendix $1"; + $title = $footnotetitle = "Appendix $1: "; + foreach $i (@$pname) { + $ww = &word_hlp($i,1); + $title .= $ww, $footnotetitle .= &word_hlp($i,0) unless $ww eq "\001"; + } + print "\\page\n"; + printf "#{\\footnote %s}\n", &hlp_sectkw($node); + print "\${\\footnote $footnotetitle}\n"; + printf "+{\\footnote browse:%05d}\n", ++$browse; + printf "!{\\footnote ChangeButtonBinding(\"btn_up\"," . + "\"JumpId(\`nasmdoc.hlp',\`%s')\");\n", + &hlp_sectkw($tstruct_up{$node}); + print "EnableButton(\"btn_up\")}\n"; + &hlp_keywords($node); + print "\\keepn\\f2\\b\\fs30\\sb60\\sa60\n"; + print "$title\n"; + $newpar = "\\par\\pard\\plain\\sb120\n"; + } elsif ($ptype eq "head" || $ptype eq "subh") { + # Heading or subheading. Begin a new node. + &hlp_menu($node) + if $tstruct_level{$tstruct_next{$node}} > $tstruct_level{$node}; + $pflags =~ /.... (.*) :(.*)/; + $node = "Section $1"; + $title = $footnotetitle = "$1. "; + foreach $i (@$pname) { + $ww = &word_hlp($i,1); + $title .= $ww, $footnotetitle .= &word_hlp($i,0) unless $ww eq "\001"; + } + print "\\page\n"; + printf "#{\\footnote %s}\n", &hlp_sectkw($node); + print "\${\\footnote $footnotetitle}\n"; + printf "+{\\footnote browse:%05d}\n", ++$browse; + printf "!{\\footnote ChangeButtonBinding(\"btn_up\"," . + "\"JumpId(\`nasmdoc.hlp',\`%s')\");\n", + &hlp_sectkw($tstruct_up{$node}); + print "EnableButton(\"btn_up\")}\n"; + &hlp_keywords($node); + print "\\keepn\\f2\\b\\fs30\\sb60\\sa60\n"; + print "$title\n"; + $newpar = "\\par\\pard\\plain\\sb120\n"; + } elsif ($ptype eq "code") { + # Code paragraph. + print "\\keep\\f1\\sb120\n"; + foreach $i (@$pname) { + warn "code line longer than 68 chars: $i\n" if length $i > 68; + $i =~ s/\\/\\\\/g; + $i =~ s/\{/\\\{/g; + $i =~ s/\}/\\\}/g; + print "$i\\par\\sb0\n"; + } + $newpar = "\\pard\\f0\\sb120\n"; + } elsif ($ptype eq "bull" || $ptype eq "norm") { + # Ordinary paragraph, optionally bulleted. We wrap, FWIW. + if ($ptype eq "bull") { + print "\\tx360\\li360\\fi-360{\\f3\\'9F}\\tab\n"; + $newpar = "\\par\\pard\\sb120\n"; + } else { + $newpar = "\\par\\sb120\n"; + } + $line = ''; + @a = @$pname; + $wd = $wprev = ''; + do { + do { $w = &word_hlp((shift @a),1); } while $w eq "\001"; # hack + $wd .= $wprev; + if ($w eq ' ' || $w eq '' || $w eq undef) { + if (length ($line . $wd) > 75) { + $line =~ s/\s*$//; # trim trailing spaces + print "$line \n"; # and put one back + $line = ''; + $wd =~ s/^\s*//; # trim leading spaces + } + $line .= $wd; + $wd = ''; + } + $wprev = $w; + } while ($w ne '' && $w ne undef); + if ($line =~ /\S/) { + $line =~ s/\s*$//; # trim trailing spaces + print "$line\n"; + } + } + } + + # Close file. + print "\\page}\n"; + select STDOUT; + close TEXT; +} + +sub word_hlp { + my ($w, $docode) = @_; + my $wtype, $wmajt; + + return undef if $w eq '' || $w eq undef; + $wtype = substr($w,0,2); + $wmajt = substr($wtype,0,1); + $w = substr($w,2); + $w =~ s/\\/\\\\/g; + $w =~ s/\{/\\\{/g; + $w =~ s/\}/\\\}/g; + $w =~ s/<.*>// if $wmajt eq "w"; # remove web links + substr($w,0,length($w)-1) =~ s/-/\\'AD/g if $wmajt ne "x"; #nonbreakhyphens + if ($wmajt eq "n" || $wtype eq "e " || $wtype eq "w ") { + return $w; + } elsif ($wtype eq "sp") { + return ' '; + } elsif ($wtype eq "da") { + return "\\'96"; + } elsif ($wmajt eq "c" || $wtype eq "wc") { + $w =~ s/ /\\'A0/g; # make spaces non-breaking + return $docode ? "{\\f1 ${w}}" : $w; + } elsif ($wtype eq "es") { + return "{\\i ${w}"; + } elsif ($wtype eq "ee") { + return "${w}}"; + } elsif ($wtype eq "eo") { + return "{\\i ${w}}"; + } elsif ($wtype eq "x ") { + return "{\\uldb "; + } elsif ($wtype eq "xe") { + $w = &hlp_sectkw($w); + return "}{\\v ${w}}"; + } elsif ($wmajt eq "i") { + return "\001"; + } else { + die "panic in word_hlp: $wtype$w\n"; + } +} + +sub hlp_menu { + my ($topitem) = @_; + my $item, $kword, $i, $mpname, $title; + + $item = $tstruct_next{$topitem}; + print "\\li360\\fi-360\n"; + while ($item) { + $title = ""; + $mpname = $tstruct_pname{$item}; + foreach $i (@$mpname) { + $ww = &word_hlp($i, 0); + $title .= $ww unless $ww eq "\001"; + } + $kword = &hlp_sectkw($item); + print "{\\uldb ${item}: $title}{\\v $kword}\\par\\sb0\n"; + $item = $tstruct_mnext{$item}; + } + print "\\pard\\sb120\n"; +} + +sub hlp_sectkw { + my ($node) = @_; + $node =~ tr/A-Z/a-z/; + $node =~ tr/- ./___/; + $node; +} + +sub hlp_keywords { + my ($node) = @_; + my $pfx = "K{\\footnote "; + my $done = 0; + foreach $i (0..$#itags) { + (print $pfx,$hlp_index[$i]), $pfx = ";\n", $done++ + if $idxnodes{$node,$itags[$i]}; + } + print "}\n" if $done; +} + +# Make tree structures. $tstruct_* is top-level and global. +sub add_item { + my ($item, $level) = @_; + my $i; + + $tstruct_pname{$item} = $pname; + $tstruct_next{$tstruct_previtem} = $item; + $tstruct_prev{$item} = $tstruct_previtem; + $tstruct_level{$item} = $level; + $tstruct_up{$item} = $tstruct_last[$level-1]; + $tstruct_mnext{$tstruct_last[$level]} = $item; + $tstruct_last[$level] = $item; + for ($i=$level+1; $i<$MAXLEVEL; $i++) { $tstruct_last[$i] = undef; } + $tstruct_previtem = $item; + push @nodes, $item; +} + +# PostScript font metric data. Used for line breaking. +sub font_metrics { + @timesr = ( + 250, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 250, 333, 408, 500, 500, 833, 778, 333, + 333, 333, 500, 564, 250, 333, 250, 278, + 500, 500, 500, 500, 500, 500, 500, 500, + 500, 500, 278, 278, 564, 564, 564, 444, + 921, 722, 667, 667, 722, 611, 556, 722, + 722, 333, 389, 722, 611, 889, 722, 722, + 556, 722, 667, 556, 611, 722, 722, 944, + 722, 722, 611, 333, 278, 333, 469, 500, + 333, 444, 500, 444, 500, 444, 333, 500, + 500, 278, 278, 500, 278, 778, 500, 500, + 500, 500, 333, 389, 278, 500, 500, 722, + 500, 500, 444, 480, 200, 480, 541, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 333, 500, 500, 167, 500, 500, 500, + 500, 180, 444, 500, 333, 333, 556, 556, + 0, 500, 500, 500, 250, 0, 453, 350, + 333, 444, 444, 500,1000,1000, 0, 444, + 0, 333, 333, 333, 333, 333, 333, 333, + 333, 0, 333, 333, 0, 333, 333, 333, + 1000, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 889, 0, 276, 0, 0, 0, 0, + 611, 722, 889, 310, 0, 0, 0, 0, + 0, 667, 0, 0, 0, 278, 0, 0, + 278, 500, 722, 500, 0, 0, 0, 0 + ); + @timesi = ( + 250, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 250, 333, 420, 500, 500, 833, 778, 333, + 333, 333, 500, 675, 250, 333, 250, 278, + 500, 500, 500, 500, 500, 500, 500, 500, + 500, 500, 333, 333, 675, 675, 675, 500, + 920, 611, 611, 667, 722, 611, 611, 722, + 722, 333, 444, 667, 556, 833, 667, 722, + 611, 722, 611, 500, 556, 722, 611, 833, + 611, 556, 556, 389, 278, 389, 422, 500, + 333, 500, 500, 444, 500, 444, 278, 500, + 500, 278, 278, 444, 278, 722, 500, 500, + 500, 500, 389, 389, 278, 500, 444, 667, + 444, 444, 389, 400, 275, 400, 541, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 389, 500, 500, 167, 500, 500, 500, + 500, 214, 556, 500, 333, 333, 500, 500, + 0, 500, 500, 500, 250, 0, 523, 350, + 333, 556, 556, 500, 889,1000, 0, 500, + 0, 333, 333, 333, 333, 333, 333, 333, + 333, 0, 333, 333, 0, 333, 333, 333, + 889, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 889, 0, 276, 0, 0, 0, 0, + 556, 722, 944, 310, 0, 0, 0, 0, + 0, 667, 0, 0, 0, 278, 0, 0, + 278, 500, 667, 500, 0, 0, 0, 0 + ); + @courr = ( + 600, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 0, 600, 600, 600, 600, 0, 600, 600, + 600, 600, 600, 600, 600, 600, 0, 600, + 0, 600, 600, 600, 600, 600, 600, 600, + 600, 0, 600, 600, 0, 600, 600, 600, + 600, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 600, 0, 600, 0, 0, 0, 0, + 600, 600, 600, 600, 0, 0, 0, 0, + 0, 600, 0, 0, 0, 600, 0, 0, + 600, 600, 600, 600, 0, 0, 0, 0 + ); +} |