mirror of
https://github.com/netwide-assembler/nasm.git
synced 2024-11-27 08:10:07 +08:00
2329 lines
69 KiB
Perl
2329 lines
69 KiB
Perl
#!/usr/bin/perl
|
|
|
|
# Read the source-form of the NASM manual and generate the various
|
|
# output forms.
|
|
|
|
# TODO:
|
|
#
|
|
# 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 ref_ps {
|
|
my($r) = @_;
|
|
$r =~ s/\./_/g;
|
|
return 'n'.$r;
|
|
}
|
|
|
|
sub ps_write_bookmarks {
|
|
my $para;
|
|
my %nchildren = ();
|
|
my %titles = ();
|
|
my @reflist = ();
|
|
my $ref, $pref, $i, $title;
|
|
|
|
for ($para = 0; $para <= $#pnames; $para++) {
|
|
my $pname = $pnames[$para];
|
|
my $pflags = $pflags[$para];
|
|
my $ptype = substr($pflags,0,4);
|
|
|
|
if ($ptype eq "chap" || $ptype eq "appn") {
|
|
# Chapter/appendix heading. "Chapter N: Title" followed by a line of
|
|
# minus signs.
|
|
|
|
$pflags =~ /(chap|appn) (.*) :(.*)/;
|
|
$ref = &ref_ps($2);
|
|
$title = '';
|
|
foreach $i (@$pname) {
|
|
$title .= &word_ps_title($i);
|
|
}
|
|
$titles{$ref} = $title;
|
|
push @reflist, $ref;
|
|
} elsif ($ptype eq "head" || $ptype eq "subh") {
|
|
# Heading/subheading. Just a number and some text.
|
|
$pflags =~ /.... (.*) :(.*)/;
|
|
$ref = &ref_ps($1);
|
|
$ref =~ /^(n[0-9A-Za-z_]+)\_[0-9A-Za-z]+$/;
|
|
$pref = $1;
|
|
|
|
$title = '';
|
|
foreach $i (@$pname) {
|
|
$title .= &word_ps_title($i);
|
|
}
|
|
$titles{$ref} = $title;
|
|
push @reflist, $ref;
|
|
$nchildren{$pref}++;
|
|
}
|
|
}
|
|
|
|
# Now we should have enough data to generate the bookmarks
|
|
print "[/Title (Contents) /Dest /nContents /OUT pdfmark";
|
|
foreach $i ( @reflist ) {
|
|
print '[/Title (', $titles{$i}, ")\n";
|
|
print '/Count -', $nchildren{$i}, ' ' if ( $nchildren{$i} );
|
|
print "/Dest /$i /OUT pdfmark\n";
|
|
}
|
|
print "[/Title (Index) /Dest /nIndex /OUT pdfmark\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 = ();
|
|
|
|
$linewidth = 468; # ADJUSTABLE: width of a normal text line
|
|
$bulletadj = 12; # ADJUSTABLE: space for a bullet
|
|
|
|
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, "B".&ref_ps($1), "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, "B".&ref_ps($1), "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, "B".&ref_ps($1), "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, "B".&ref_ps($1), "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 = $linewidth - $bulletadj;
|
|
$type = $begtype = "bbeg";
|
|
$bodytype = "bbdy";
|
|
$onetype = "bone";
|
|
$endtype = "bend";
|
|
} else {
|
|
$width = $linewidth;
|
|
$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 = ("BnContents", "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,2,0," " if ($ltypes[$i] !~ /chap/);
|
|
push @$clname,$i; # placeholder for page number
|
|
push @clnames,$clname++;
|
|
push @cltypes,"C" . substr($ltypes[$i],0,3);
|
|
}
|
|
}
|
|
@$clname = ("BnIndex", "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$/) {
|
|
$pnum += 1 - ($pnum & 1); # advance to odd numbered page if necessary
|
|
$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 = $3, $inumc = $2; $inum = $1;
|
|
@pnum = (" ", "Bp$inum", "n$inum", "E");
|
|
push(@pnum, "n$inumc") if ( $inumc ne '' );
|
|
$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;
|
|
&ps_write_bookmarks;
|
|
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", ["BnIndex", "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($page);
|
|
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 = <<'EOF';
|
|
/sp (n ) def
|
|
/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
|
|
/B 16#42 def /E 16#45 def /D 16#44 def
|
|
/min { 2 copy gt { exch } if pop } def
|
|
/max { 2 copy lt { exch } if pop } def
|
|
/lkbegun 0 def
|
|
/lkury 0 def
|
|
/lkurx 0 def
|
|
/lklly 0 def
|
|
/lkllx 0 def
|
|
/lktarget () def
|
|
/linkbegin {
|
|
/lkbegun 1 def
|
|
/lktarget exch cvn def
|
|
} def
|
|
/linkshow {
|
|
lkbegun 0 ne {
|
|
gsave dup true charpath pathbbox grestore
|
|
lkbegun 1 eq {
|
|
/lkury exch def
|
|
/lkurx exch def
|
|
/lklly exch def
|
|
/lkllx exch def
|
|
/lkbegun 2 def
|
|
} {
|
|
lkury max /lkury exch def
|
|
lkurx max /lkurx exch def
|
|
lklly min /lklly exch def
|
|
lkllx min /lkllx exch def
|
|
} ifelse
|
|
} if
|
|
show
|
|
} def
|
|
/linkend {
|
|
[/Rect [ lkllx lklly lkurx lkury ]
|
|
/Color [ 1.0 0.0 0.0 ]
|
|
/Border [0 0 0]
|
|
/Dest lktarget
|
|
/Subtype /Link
|
|
/ANN pdfmark
|
|
/lkbegun 0 def
|
|
} def
|
|
/linkdest {
|
|
/lkdest exch cvn def
|
|
[ /Dest lkdest
|
|
/View [ /XYZ currentpoint 0 ]
|
|
/DEST pdfmark
|
|
} def
|
|
/handlelink {
|
|
dup 0 get
|
|
dup B eq {
|
|
pop dup length 1 sub 1 exch getinterval linkbegin
|
|
} {
|
|
E eq {
|
|
pop linkend
|
|
} {
|
|
dup length 1 sub 1 exch getinterval linkdest
|
|
} ifelse
|
|
} ifelse
|
|
} def
|
|
/pageodd {
|
|
550 50 moveto ns setfont dup stringwidth pop neg 0 rmoveto show
|
|
} def
|
|
/pageeven { 50 50 moveto ns setfont show } def
|
|
/destmark {
|
|
dup length 1 sub 1 exch getinterval linkdest
|
|
} def
|
|
/chapter {
|
|
100 620 moveto
|
|
dup 0 get destmark
|
|
dup length 1 sub 1 exch getinterval
|
|
{
|
|
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 destmark
|
|
a 1 get dup length 1 sub 1 exch getinterval
|
|
nh setfont dup stringwidth pop neg 0 rmoveto show
|
|
100 y moveto
|
|
a dup length 2 sub 2 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 destmark
|
|
a 1 get dup length 1 sub 1 exch getinterval
|
|
ns setfont dup stringwidth pop neg 0 rmoveto show
|
|
100 y moveto
|
|
a dup length 2 sub 2 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 E le {
|
|
pop s handlelink
|
|
} {
|
|
dup n eq {pop nf setfont} {
|
|
e eq {ef setfont} {cf setfont} ifelse
|
|
} ifelse
|
|
s s length 1 sub 1 exch getinterval linkshow
|
|
s sp eq {j 0 rmoveto} if
|
|
} ifelse
|
|
} 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
|
|
/ss exch def
|
|
nf setfont 568 ss stringwidth pop sub /ex exch def
|
|
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 (.) linkshow
|
|
} if
|
|
} for
|
|
ex yy moveto ss linkshow
|
|
linkend
|
|
} 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 E le {
|
|
pop
|
|
} {
|
|
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
|
|
} ifelse
|
|
} forall
|
|
a y x 0 disp
|
|
} def
|
|
/left {0 disp} def
|
|
/bullet {
|
|
nf setfont dup 100 exch 689 exch sub moveto (\267) show
|
|
} def
|
|
[/PageMode /UseOutlines /DOCVIEW pdfmark
|
|
EOF
|
|
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";
|
|
print "%%BeginProlog\n";
|
|
# This makes sure non-PDF PostScript interpreters don't choke on
|
|
# pdfmarks in the output
|
|
print "/pdfmark where\n";
|
|
print "{pop} {userdict /pdfmark /cleartomark load put} ifelse\n";
|
|
print "%%EndProlog\n";
|
|
print "%%BeginSetup\n";
|
|
print "save\n";
|
|
$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 {
|
|
my ($oldpg) = @_;
|
|
&ps_donepg($oldpg);
|
|
print "%%Trailer\nrestore\n%%EOF\n";
|
|
}
|
|
|
|
sub ps_throw_pg {
|
|
my ($oldpg, $newpg) = @_;
|
|
while ($oldpg < $newpg) {
|
|
&ps_donepg($oldpg);
|
|
$oldpg++;
|
|
&ps_initpg($oldpg);
|
|
}
|
|
}
|
|
|
|
sub ps_initpg {
|
|
my ($pgnum) = @_;
|
|
print "%%Page: $pgnum $pgnum\n";
|
|
print "%%BeginPageSetup\nsave\n%%EndPageSetup\n";
|
|
print "95 705 moveto (p$pgnum) linkdest\n";
|
|
}
|
|
|
|
sub ps_donepg {
|
|
my ($pgnum) = @_;
|
|
if ($pgnum & 1) {
|
|
print "%%PageTrailer\n($pgnum)pageodd restore showpage\n";
|
|
} else {
|
|
print "%%PageTrailer\n($pgnum)pageeven restore 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 word_ps_title {
|
|
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 $w;
|
|
} elsif ($wtype eq "sp") {
|
|
return ' ';
|
|
} elsif ($wtype eq "da") {
|
|
return '-';
|
|
} elsif ($wmajt eq "c" || $wtype eq "wc") {
|
|
return $w;
|
|
} elsif ($wmajt eq "e") {
|
|
return $w;
|
|
} elsif ($wmajt eq "x") {
|
|
return '';
|
|
} elsif ($wtype eq "i ") {
|
|
return '';
|
|
} else {
|
|
die "panic in word_ps_title: $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);
|
|
if ( $f !~ /^[BDE]$/ ) {
|
|
$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 "\@dircategory Programming\n";
|
|
print "\@direntry\n";
|
|
print "* NASM: (nasm). The Netwide Assembler for x86.\n";
|
|
print "\@end direntry\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 Netwide Assembler\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";
|
|
$hdr = ($ptype eq "subh" ? "\@unnumberedsubsec" : "\@unnumberedsec");
|
|
print "$hdr $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
|
|
);
|
|
}
|