summaryrefslogtreecommitdiffstats
path: root/Doc/tools
diff options
context:
space:
mode:
Diffstat (limited to 'Doc/tools')
-rwxr-xr-xDoc/tools/anno-api.py71
-rwxr-xr-xDoc/tools/buildindex.py397
-rw-r--r--Doc/tools/checkargs.pm112
-rwxr-xr-xDoc/tools/cklatex26
-rwxr-xr-xDoc/tools/cmpcsyms157
-rw-r--r--Doc/tools/custlib.py78
-rwxr-xr-xDoc/tools/findcsyms136
-rwxr-xr-xDoc/tools/findmodrefs63
-rwxr-xr-xDoc/tools/findsyms128
-rwxr-xr-xDoc/tools/fix_hack2
-rwxr-xr-xDoc/tools/fix_libaux.sed3
-rw-r--r--Doc/tools/fixinfo.el15
-rwxr-xr-xDoc/tools/getpagecounts97
-rwxr-xr-xDoc/tools/getversioninfo71
-rwxr-xr-xDoc/tools/html2texi.pl1750
-rwxr-xr-xDoc/tools/indfix.py100
-rw-r--r--Doc/tools/keywords.py25
-rwxr-xr-xDoc/tools/listmodules182
-rw-r--r--Doc/tools/listmodules.py125
-rwxr-xr-xDoc/tools/makesec.sh129
-rwxr-xr-xDoc/tools/mkackshtml65
-rwxr-xr-xDoc/tools/mkhowto659
-rwxr-xr-xDoc/tools/mkinfo65
-rwxr-xr-xDoc/tools/mkmodindex158
-rwxr-xr-xDoc/tools/mkpkglist85
-rwxr-xr-xDoc/tools/mksourcepkg164
-rwxr-xr-xDoc/tools/node2label.pl71
-rw-r--r--Doc/tools/prechm.py519
-rwxr-xr-xDoc/tools/push-docs.sh138
-rw-r--r--Doc/tools/py2texi.el970
-rw-r--r--Doc/tools/refcounts.py97
-rw-r--r--Doc/tools/rewrite.py54
-rw-r--r--Doc/tools/sgmlconv/Makefile67
-rw-r--r--Doc/tools/sgmlconv/README58
-rw-r--r--Doc/tools/sgmlconv/conversion.xml914
-rwxr-xr-xDoc/tools/sgmlconv/docfixer.py1072
-rwxr-xr-xDoc/tools/sgmlconv/esis2sgml.py263
-rw-r--r--Doc/tools/sgmlconv/esistools.py312
-rwxr-xr-xDoc/tools/sgmlconv/latex2esis.py566
-rw-r--r--Doc/tools/sgmlconv/make.rules48
-rw-r--r--Doc/tools/support.py202
-rwxr-xr-xDoc/tools/toc2bkm.py160
-rw-r--r--Doc/tools/undoc_symbols.py93
-rwxr-xr-xDoc/tools/update-docs.sh31
-rwxr-xr-xDoc/tools/whichlibs2
45 files changed, 0 insertions, 10500 deletions
diff --git a/Doc/tools/anno-api.py b/Doc/tools/anno-api.py
deleted file mode 100755
index b4b7f79..0000000
--- a/Doc/tools/anno-api.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#! /usr/bin/env python
-"""Add reference count annotations to the Python/C API Reference."""
-__version__ = '$Revision$'
-
-import getopt
-import os
-import sys
-
-import refcounts
-
-
-PREFIX_1 = r"\begin{cfuncdesc}{PyObject*}{"
-PREFIX_2 = r"\begin{cfuncdesc}{PyVarObject*}{"
-
-
-def main():
- rcfile = os.path.join(os.path.dirname(refcounts.__file__), os.pardir,
- "api", "refcounts.dat")
- outfile = "-"
- opts, args = getopt.getopt(sys.argv[1:], "o:r:", ["output=", "refcounts="])
- for opt, arg in opts:
- if opt in ("-o", "--output"):
- outfile = arg
- elif opt in ("-r", "--refcounts"):
- rcfile = arg
- rcdict = refcounts.load(rcfile)
- if outfile == "-":
- output = sys.stdout
- else:
- output = open(outfile, "w")
- if not args:
- args = ["-"]
- for infile in args:
- if infile == "-":
- input = sys.stdin
- else:
- input = open(infile)
- while 1:
- line = input.readline()
- if not line:
- break
- prefix = None
- if line.startswith(PREFIX_1):
- prefix = PREFIX_1
- elif line.startswith(PREFIX_2):
- prefix = PREFIX_2
- if prefix:
- s = line[len(prefix):].split('}', 1)[0]
- try:
- info = rcdict[s]
- except KeyError:
- sys.stderr.write("No refcount data for %s\n" % s)
- else:
- if info.result_type in ("PyObject*", "PyVarObject*"):
- if info.result_refs is None:
- rc = "Always \NULL{}"
- else:
- rc = info.result_refs and "New" or "Borrowed"
- rc = rc + " reference"
- line = (r"\begin{cfuncdesc}[%s]{%s}{"
- % (rc, info.result_type)) \
- + line[len(prefix):]
- output.write(line)
- if infile != "-":
- input.close()
- if outfile != "-":
- output.close()
-
-
-if __name__ == "__main__":
- main()
diff --git a/Doc/tools/buildindex.py b/Doc/tools/buildindex.py
deleted file mode 100755
index 0e5ba84..0000000
--- a/Doc/tools/buildindex.py
+++ /dev/null
@@ -1,397 +0,0 @@
-#! /usr/bin/env python
-
-__version__ = '$Revision$'
-
-import os.path
-import re
-import string
-import sys
-
-from xml.sax.saxutils import quoteattr
-
-
-bang_join = "!".join
-null_join = "".join
-
-REPLACEMENTS = [
- # Hackish way to deal with macros replaced with simple text
- (re.compile(r"\\ABC\b"), "ABC"),
- (re.compile(r"\\ASCII\b"), "ASCII"),
- (re.compile(r"\\Cpp\b"), "C++"),
- (re.compile(r"\\EOF\b"), "EOF"),
- (re.compile(r"\\NULL\b"), "NULL"),
- (re.compile(r"\\POSIX\b"), "POSIX"),
- (re.compile(r"\\UNIX\b"), "Unix"),
- # deal with turds left over from LaTeX2HTML
- (re.compile(r"<#\d+#>"), ""),
- ]
-
-class Node:
- continuation = 0
-
- def __init__(self, link, str, seqno):
- self.links = [link]
- self.seqno = seqno
- for pattern, replacement in REPLACEMENTS:
- str = pattern.sub(replacement, str)
- # build up the text
- self.text = split_entry_text(str)
- self.key = list(split_entry_key(str))
-
- def __eq__(self, other):
- return cmp(self, other) == 0
-
- def __lt__(self, other):
- return cmp(self, other) == -1
-
- def __gt__(self, other):
- return cmp(self, other) == 1
-
- def __cmp__(self, other):
- """Comparison operator includes sequence number, for use with
- list.sort()."""
- return self.cmp_entry(other) or cmp(self.seqno, other.seqno)
-
- def cmp_entry(self, other):
- """Comparison 'operator' that ignores sequence number."""
- c = 0
- for i in range(min(len(self.key), len(other.key))):
- c = (cmp_part(self.key[i], other.key[i])
- or cmp_part(self.text[i], other.text[i]))
- if c:
- break
- return c or cmp(self.key, other.key) or cmp(self.text, other.text)
-
- def __repr__(self):
- return "<Node for %s (%s)>" % (bang_join(self.text), self.seqno)
-
- def __str__(self):
- return bang_join(self.key)
-
- def dump(self):
- return "%s\1%s###%s\n" \
- % ("\1".join(self.links),
- bang_join(self.text),
- self.seqno)
-
-
-def cmp_part(s1, s2):
- result = cmp(s1, s2)
- if result == 0:
- return 0
- l1 = s1.lower()
- l2 = s2.lower()
- minlen = min(len(s1), len(s2))
- if len(s1) < len(s2) and l1 == l2[:len(s1)]:
- result = -1
- elif len(s2) < len(s1) and l2 == l1[:len(s2)]:
- result = 1
- else:
- result = cmp(l1, l2) or cmp(s1, s2)
- return result
-
-
-def split_entry(str, which):
- stuff = []
- parts = str.split('!')
- parts = [part.split('@') for part in parts]
- for entry in parts:
- if len(entry) != 1:
- key = entry[which]
- else:
- key = entry[0]
- stuff.append(key)
- return stuff
-
-
-_rmtt = re.compile(r"""(.*)<tt(?: class=['"][a-z0-9]+["'])?>(.*)</tt>(.*)$""",
- re.IGNORECASE)
-_rmparens = re.compile(r"\(\)")
-
-def split_entry_key(str):
- parts = split_entry(str, 1)
- for i in range(len(parts)):
- m = _rmtt.match(parts[i])
- if m:
- parts[i] = null_join(m.group(1, 2, 3))
- else:
- parts[i] = parts[i].lower()
- # remove '()' from the key:
- parts[i] = _rmparens.sub('', parts[i])
- return map(trim_ignored_letters, parts)
-
-
-def split_entry_text(str):
- if '<' in str:
- m = _rmtt.match(str)
- if m:
- str = null_join(m.group(1, 2, 3))
- return split_entry(str, 1)
-
-
-def load(fp):
- nodes = []
- rx = re.compile("(.*)\1(.*)###(.*)$")
- while 1:
- line = fp.readline()
- if not line:
- break
- m = rx.match(line)
- if m:
- link, str, seqno = m.group(1, 2, 3)
- nodes.append(Node(link, str, seqno))
- return nodes
-
-
-def trim_ignored_letters(s):
- # ignore $ to keep environment variables with the
- # leading letter from the name
- if s.startswith("$"):
- return s[1:].lower()
- else:
- return s.lower()
-
-def get_first_letter(s):
- if s.startswith("<tex2html_percent_mark>"):
- return "%"
- else:
- return trim_ignored_letters(s)[0]
-
-
-def split_letters(nodes):
- letter_groups = []
- if nodes:
- group = []
- append = group.append
- letter = get_first_letter(nodes[0].text[0])
- letter_groups.append((letter, group))
- for node in nodes:
- nletter = get_first_letter(node.text[0])
- if letter != nletter:
- letter = nletter
- group = []
- letter_groups.append((letter, group))
- append = group.append
- append(node)
- return letter_groups
-
-
-def group_symbols(groups):
- entries = []
- ident_letters = string.ascii_letters + "_"
- while groups[0][0] not in ident_letters:
- entries += groups[0][1]
- del groups[0]
- if entries:
- groups.insert(0, ("Symbols", entries))
-
-
-# need a function to separate the nodes into columns...
-def split_columns(nodes, columns=1):
- if columns <= 1:
- return [nodes]
- # This is a rough height; we may have to increase to avoid breaks before
- # a subitem.
- colheight = int(len(nodes) / columns)
- numlong = int(len(nodes) % columns)
- if numlong:
- colheight = colheight + 1
- else:
- numlong = columns
- cols = []
- for i in range(numlong):
- start = i * colheight
- end = start + colheight
- cols.append(nodes[start:end])
- del nodes[:end]
- colheight = colheight - 1
- try:
- numshort = int(len(nodes) / colheight)
- except ZeroDivisionError:
- cols = cols + (columns - len(cols)) * [[]]
- else:
- for i in range(numshort):
- start = i * colheight
- end = start + colheight
- cols.append(nodes[start:end])
- #
- # If items continue across columns, make sure they are marked
- # as continuations so the user knows to look at the previous column.
- #
- for i in range(len(cols) - 1):
- try:
- prev = cols[i][-1]
- next = cols[i + 1][0]
- except IndexError:
- return cols
- else:
- n = min(len(prev.key), len(next.key))
- for j in range(n):
- if prev.key[j] != next.key[j]:
- break
- next.continuation = j + 1
- return cols
-
-
-DL_LEVEL_INDENT = " "
-
-def format_column(nodes):
- strings = ["<dl compact='compact'>"]
- append = strings.append
- level = 0
- previous = []
- for node in nodes:
- current = node.text
- count = 0
- for i in range(min(len(current), len(previous))):
- if previous[i] != current[i]:
- break
- count = i + 1
- if count > level:
- append("<dl compact='compact'>" * (count - level) + "\n")
- level = count
- elif level > count:
- append("\n")
- append(level * DL_LEVEL_INDENT)
- append("</dl>" * (level - count))
- level = count
- # else: level == count
- for i in range(count, len(current) - 1):
- term = node.text[i]
- level = level + 1
- if node.continuation > i:
- extra = " (continued)"
- else:
- extra = ""
- append("\n<dt>%s%s\n<dd>\n%s<dl compact='compact'>"
- % (term, extra, level * DL_LEVEL_INDENT))
- append("\n%s<dt>%s%s</a>"
- % (level * DL_LEVEL_INDENT, node.links[0], node.text[-1]))
- for link in node.links[1:]:
- append(",\n%s %s[Link]</a>" % (level * DL_LEVEL_INDENT, link))
- previous = current
- append("\n")
- append("</dl>" * (level + 1))
- return null_join(strings)
-
-
-def format_nodes(nodes, columns=1):
- strings = []
- append = strings.append
- if columns > 1:
- colnos = range(columns)
- colheight = int(len(nodes) / columns)
- if len(nodes) % columns:
- colheight = colheight + 1
- colwidth = int(100 / columns)
- append('<table width="100%"><tr valign="top">')
- for col in split_columns(nodes, columns):
- append('<td width="%d%%">\n' % colwidth)
- append(format_column(col))
- append("\n</td>")
- append("\n</tr></table>")
- else:
- append(format_column(nodes))
- return null_join(strings)
-
-
-def format_letter(letter):
- if letter == '.':
- lettername = ". (dot)"
- elif letter == '_':
- lettername = "_ (underscore)"
- else:
- lettername = letter.capitalize()
- return "\n<hr />\n<h2 id=%s>%s</h2>\n\n" \
- % (quoteattr("letter-" + letter), lettername)
-
-
-def format_html_letters(nodes, columns, group_symbol_nodes):
- letter_groups = split_letters(nodes)
- if group_symbol_nodes:
- group_symbols(letter_groups)
- items = []
- for letter, nodes in letter_groups:
- s = "<b><a href=\"#letter-%s\">%s</a></b>" % (letter, letter)
- items.append(s)
- s = ["<hr /><center>\n%s</center>\n" % " |\n".join(items)]
- for letter, nodes in letter_groups:
- s.append(format_letter(letter))
- s.append(format_nodes(nodes, columns))
- return null_join(s)
-
-def format_html(nodes, columns):
- return format_nodes(nodes, columns)
-
-
-def collapse(nodes):
- """Collapse sequences of nodes with matching keys into a single node.
- Destructive."""
- if len(nodes) < 2:
- return
- prev = nodes[0]
- i = 1
- while i < len(nodes):
- node = nodes[i]
- if not node.cmp_entry(prev):
- prev.links.append(node.links[0])
- del nodes[i]
- else:
- i = i + 1
- prev = node
-
-
-def dump(nodes, fp):
- for node in nodes:
- fp.write(node.dump())
-
-
-def process_nodes(nodes, columns, letters=0, group_symbol_nodes=0):
- nodes.sort()
- collapse(nodes)
- if letters:
- return format_html_letters(nodes, columns, group_symbol_nodes)
- else:
- return format_html(nodes, columns)
-
-
-def main():
- import getopt
- ifn = "-"
- ofn = "-"
- columns = 1
- letters = 0
- group_symbol_nodes = 1
- opts, args = getopt.getopt(sys.argv[1:], "c:lo:",
- ["columns=", "dont-group-symbols",
- "group-symbols", "letters", "output="])
- for opt, val in opts:
- if opt in ("-o", "--output"):
- ofn = val
- elif opt in ("-c", "--columns"):
- columns = int(val, 10)
- elif opt in ("-l", "--letters"):
- letters = 1
- elif opt == "--group-symbols":
- group_symbol_nodes = 1
- elif opt == "--dont-group-symbols":
- group_symbol_nodes = 0
- if not args:
- args = [ifn]
- nodes = []
- for fn in args:
- nodes = nodes + load(open(fn))
- num_nodes = len(nodes)
- html = process_nodes(nodes, columns, letters, group_symbol_nodes)
- program = os.path.basename(sys.argv[0])
- if ofn == "-":
- sys.stdout.write(html)
- sys.stderr.write("\n%s: %d index nodes" % (program, num_nodes))
- else:
- open(ofn, "w").write(html)
- print()
- print("%s: %d index nodes" % (program, num_nodes))
-
-
-if __name__ == "__main__":
- main()
diff --git a/Doc/tools/checkargs.pm b/Doc/tools/checkargs.pm
deleted file mode 100644
index 005d3c6..0000000
--- a/Doc/tools/checkargs.pm
+++ /dev/null
@@ -1,112 +0,0 @@
-#! /usr/bin/perl
-
-package checkargs;
-require 5.004; # uses "for my $var"
-require Exporter;
-@ISA = qw(Exporter);
-@EXPORT = qw(check_args check_args_range check_args_at_least);
-use strict;
-use Carp;
-
-=head1 NAME
-
-checkargs -- Provide rudimentary argument checking for perl5 functions
-
-=head1 SYNOPSIS
-
- check_args(cArgsExpected, @_)
- check_args_range(cArgsMin, cArgsMax, @_)
- check_args_at_least(cArgsMin, @_)
-where "@_" should be supplied literally.
-
-=head1 DESCRIPTION
-
-As the first line of user-written subroutine foo, do one of the following:
-
- my ($arg1, $arg2) = check_args(2, @_);
- my ($arg1, @rest) = check_args_range(1, 4, @_);
- my ($arg1, @rest) = check_args_at_least(1, @_);
- my @args = check_args_at_least(0, @_);
-
-These functions may also be called for side effect (put a call to one
-of the functions near the beginning of the subroutine), but using the
-argument checkers to set the argument list is the recommended usage.
-
-The number of arguments and their definedness are checked; if the wrong
-number are received, the program exits with an error message.
-
-=head1 AUTHOR
-
-Michael D. Ernst <F<mernst@cs.washington.edu>>
-
-=cut
-
-## Need to check that use of caller(1) really gives desired results.
-## Need to give input chunk information.
-## Is this obviated by Perl 5.003's declarations? Not entirely, I think.
-
-sub check_args ( $@ )
-{
- my ($num_formals, @args) = @_;
- my ($pack, $file_arg, $line_arg, $subname, $hasargs, $wantarr) = caller(1);
- if (@_ < 1) { croak "check_args needs at least 7 args, got ", scalar(@_), ": @_\n "; }
- if ((!wantarray) && ($num_formals != 0))
- { croak "check_args called in scalar context"; }
- # Can't use croak below here: it would only go out to caller, not its caller
- my $num_actuals = @args;
- if ($num_actuals != $num_formals)
- { die "$file_arg:$line_arg: function $subname expected $num_formals argument",
- (($num_formals == 1) ? "" : "s"),
- ", got $num_actuals",
- (($num_actuals == 0) ? "" : ": @args"),
- "\n"; }
- for my $index (0..$#args)
- { if (!defined($args[$index]))
- { die "$file_arg:$line_arg: function $subname undefined argument ", $index+1, ": @args[0..$index-1]\n"; } }
- return @args;
-}
-
-sub check_args_range ( $$@ )
-{
- my ($min_formals, $max_formals, @args) = @_;
- my ($pack, $file_arg, $line_arg, $subname, $hasargs, $wantarr) = caller(1);
- if (@_ < 2) { croak "check_args_range needs at least 8 args, got ", scalar(@_), ": @_"; }
- if ((!wantarray) && ($max_formals != 0) && ($min_formals !=0) )
- { croak "check_args_range called in scalar context"; }
- # Can't use croak below here: it would only go out to caller, not its caller
- my $num_actuals = @args;
- if (($num_actuals < $min_formals) || ($num_actuals > $max_formals))
- { die "$file_arg:$line_arg: function $subname expected $min_formals-$max_formals arguments, got $num_actuals",
- ($num_actuals == 0) ? "" : ": @args", "\n"; }
- for my $index (0..$#args)
- { if (!defined($args[$index]))
- { die "$file_arg:$line_arg: function $subname undefined argument ", $index+1, ": @args[0..$index-1]\n"; } }
- return @args;
-}
-
-sub check_args_at_least ( $@ )
-{
- my ($min_formals, @args) = @_;
- my ($pack, $file_arg, $line_arg, $subname, $hasargs, $wantarr) = caller(1);
- # Don't do this, because we want every sub to start with a call to check_args*
- # if ($min_formals == 0)
- # { die "Isn't it pointless to check for at least zero args to $subname?\n"; }
- if (scalar(@_) < 1)
- { croak "check_args_at_least needs at least 1 arg, got ", scalar(@_), ": @_"; }
- if ((!wantarray) && ($min_formals != 0))
- { croak "check_args_at_least called in scalar context"; }
- # Can't use croak below here: it would only go out to caller, not its caller
- my $num_actuals = @args;
- if ($num_actuals < $min_formals)
- { die "$file_arg:$line_arg: function $subname expected at least $min_formals argument",
- ($min_formals == 1) ? "" : "s",
- ", got $num_actuals",
- ($num_actuals == 0) ? "" : ": @args", "\n"; }
- for my $index (0..$#args)
- { if (!defined($args[$index]))
- { warn "$file_arg:$line_arg: function $subname undefined argument ", $index+1, ": @args[0..$index-1]\n"; last; } }
- return @args;
-}
-
-1; # successful import
-__END__
diff --git a/Doc/tools/cklatex b/Doc/tools/cklatex
deleted file mode 100755
index 396e914..0000000
--- a/Doc/tools/cklatex
+++ /dev/null
@@ -1,26 +0,0 @@
-#! /bin/sh
-# -*- ksh -*-
-
-# This script *helps* locate lines of normal content that end in '}';
-# this is useful since LaTeX2HTML (at least the old version that we
-# use) breaks on many lines that end that way.
-#
-# Usage: cklatex files... | less
-#
-# *Read* the output looking for suspicious lines!
-
-grep -n "[^ ]}\$" $@ | \
- grep -v '\\begin{' | \
- grep -v '\\end{' | \
- grep -v '\\input{' | \
- grep -v '\\documentclass{' | \
- grep -v '\\title{' | \
- grep -v '\\chapter{' | \
- grep -v '\\chapter\*{' | \
- grep -v '\\section{' | \
- grep -v '\\subsection{' | \
- grep -v '\\subsubsection{' | \
- grep -v '\\sectionauthor{' | \
- grep -v '\\moduleauthor{'
-
-exit $?
diff --git a/Doc/tools/cmpcsyms b/Doc/tools/cmpcsyms
deleted file mode 100755
index 55f9954..0000000
--- a/Doc/tools/cmpcsyms
+++ /dev/null
@@ -1,157 +0,0 @@
-#! /usr/bin/env python
-from __future__ import with_statement
-import errno
-import os
-import re
-import sys
-import string
-
-if __name__ == "__main__":
- _base = sys.argv[0]
-else:
- _base = __file__
-
-_script_home = os.path.abspath(os.path.dirname(_base))
-
-srcdir = os.path.dirname(os.path.dirname(_script_home))
-
-EXCLUDES = ["bitset.h", "cStringIO.h", "graminit.h", "grammar.h",
- "longintrepr.h", "metagrammar.h",
- "node.h", "opcode.h", "osdefs.h", "pgenheaders.h",
- "py_curses.h", "parsetok.h", "symtable.h", "token.h"]
-
-
-def list_headers():
- """Return a list of headers."""
- incdir = os.path.join(srcdir, "Include")
- return [os.path.join(incdir, fn) for fn in os.listdir(incdir)
- if fn.endswith(".h") and fn not in EXCLUDES]
-
-
-def matcher(pattern):
- return re.compile(pattern).search
-
-MATCHERS = [
- # XXX this should also deal with ctypedesc, cvardesc and cmemberdesc
- matcher(r"\\begin\{cfuncdesc\}\{(?P<result>[^}]*)\}\{(?P<sym>[^}]*)\}{(?P<params>[^}]*)\}"),
- matcher(r"\\cfuncline\{(?P<result>[^})]*)\}\{(?P<sym>[^}]*)\}{(?P<params>[^}]*)\}"),
- ]
-
-def list_documented_items():
- """Return a list of everything that's already documented."""
- apidir = os.path.join(srcdir, "Doc", "api")
- files = [fn for fn in os.listdir(apidir) if fn.endswith(".tex")]
- L = []
- for fn in files:
- fullname = os.path.join(apidir, fn)
- data = open(fullname).read()
- for matcher in MATCHERS:
- pos = 0
- while 1:
- m = matcher(data, pos)
- if not m: break
- pos = m.end()
- sym = m.group("sym")
- result = m.group("result")
- params = m.group("params")
- # replace all whitespace with a single one
- params = " ".join(params.split())
- L.append((sym, result, params, fn))
- return L
-
-def normalize_type(t):
- t = t.strip()
- s = t.rfind("*")
- if s != -1:
- # strip everything after the pointer name
- t = t[:s+1]
- # Drop the variable name
- s = t.split()
- typenames = 1
- if len(s)>1 and s[0]=='unsigned' and s[1]=='int':
- typenames = 2
- if len(s) > typenames and s[-1][0] in string.letters:
- del s[-1]
- if not s:
- print "XXX", t
- return ""
- # Drop register
- if s[0] == "register":
- del s[0]
- # discard all spaces
- return ''.join(s)
-
-def compare_type(t1, t2):
- t1 = normalize_type(t1)
- t2 = normalize_type(t2)
- if t1 == r'\moreargs' and t2 == '...':
- return False
- if t1 != t2:
- #print "different:", t1, t2
- return False
- return True
-
-
-def compare_types(ret, params, hret, hparams):
- if not compare_type(ret, hret):
- return False
- params = params.split(",")
- hparams = hparams.split(",")
- if not params and hparams == ['void']:
- return True
- if not hparams and params == ['void']:
- return True
- if len(params) != len(hparams):
- return False
- for p1, p2 in zip(params, hparams):
- if not compare_type(p1, p2):
- return False
- return True
-
-def main():
- headers = list_headers()
- documented = list_documented_items()
-
- lines = []
- for h in headers:
- data = open(h).read()
- data, n = re.subn(r"PyAPI_FUNC\(([^)]*)\)", r"\1", data)
- name = os.path.basename(h)
- with open(name, "w") as f:
- f.write(data)
- cmd = ("ctags -f - --file-scope=no --c-kinds=p --fields=S "
- "-Istaticforward -Istatichere=static " + name)
- with os.popen(cmd) as f:
- lines.extend(f.readlines())
- os.unlink(name)
- L = {}
- prevsym = None
- for line in lines:
- if not line:
- break
- sym, filename, signature = line.split(None, 2)
- if sym == prevsym:
- continue
- expr = "\^(.*)%s" % sym
- m = re.search(expr, signature)
- if not m:
- print "Could not split",signature, "using",expr
- rettype = m.group(1).strip()
- m = re.search("signature:\(([^)]*)\)", signature)
- if not m:
- print "Could not get signature from", signature
- params = m.group(1)
- L[sym] = (rettype, params)
-
- for sym, ret, params, fn in documented:
- if sym not in L:
- print "No declaration for '%s'" % sym
- continue
- hret, hparams = L[sym]
- if not compare_types(ret, params, hret, hparams):
- print "Declaration error for %s (%s):" % (sym, fn)
- print ret+": "+params
- print hret+": "+hparams
-
-if __name__ == "__main__":
- main()
diff --git a/Doc/tools/custlib.py b/Doc/tools/custlib.py
deleted file mode 100644
index 8224b2c..0000000
--- a/Doc/tools/custlib.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# Generate custlib.tex, which is a site-specific library document.
-
-# Phase I: list all the things that can be imported
-
-import glob
-import os.path
-import sys
-
-modules = {}
-
-for modname in sys.builtin_module_names:
- modules[modname] = modname
-
-for dir in sys.path:
- # Look for *.py files
- filelist = glob.glob(os.path.join(dir, '*.py'))
- for file in filelist:
- path, file = os.path.split(file)
- base, ext = os.path.splitext(file)
- modules[base.lower()] = base
-
- # Look for shared library files
- filelist = (glob.glob(os.path.join(dir, '*.so')) +
- glob.glob(os.path.join(dir, '*.sl')) +
- glob.glob(os.path.join(dir, '*.o')) )
- for file in filelist:
- path, file = os.path.split(file)
- base, ext = os.path.splitext(file)
- if base[-6:] == 'module':
- base = base[:-6]
- modules[base.lower()] = base
-
-# Minor oddity: the types module is documented in libtypes2.tex
-if 'types' in modules:
- del modules['types']
- modules['types2'] = None
-
-# Phase II: find all documentation files (lib*.tex)
-# and eliminate modules that don't have one.
-
-docs = {}
-filelist = glob.glob('lib*.tex')
-for file in filelist:
- modname = file[3:-4]
- docs[modname] = modname
-
-mlist = list(modules.keys())
-mlist = filter(lambda x, docs=docs: x in docs, mlist)
-mlist.sort()
-mlist = map(lambda x, docs=docs: docs[x], mlist)
-
-modules = mlist
-
-# Phase III: write custlib.tex
-
-# Write the boilerplate
-# XXX should be fancied up.
-print("""\documentstyle[twoside,11pt,myformat]{report}
-\\title{Python Library Reference}
-\\input{boilerplate}
-\\makeindex % tell \\index to actually write the .idx file
-\\begin{document}
-\\pagenumbering{roman}
-\\maketitle
-\\input{copyright}
-\\begin{abstract}
-\\noindent This is a customized version of the Python Library Reference.
-\\end{abstract}
-\\pagebreak
-{\\parskip = 0mm \\tableofcontents}
-\\pagebreak\\pagenumbering{arabic}""")
-
-for modname in mlist:
- print("\\input{lib%s}" % (modname,))
-
-# Write the end
-print("""\\input{custlib.ind} % Index
-\\end{document}""")
diff --git a/Doc/tools/findcsyms b/Doc/tools/findcsyms
deleted file mode 100755
index d68c3ce..0000000
--- a/Doc/tools/findcsyms
+++ /dev/null
@@ -1,136 +0,0 @@
-#! /usr/bin/env python
-
-import errno
-import os
-import re
-import sys
-
-if __name__ == "__main__":
- _base = sys.argv[0]
-else:
- _base = __file__
-
-_script_home = os.path.abspath(os.path.dirname(_base))
-
-srcdir = os.path.dirname(os.path.dirname(_script_home))
-
-EXCLUDES = ["bitset.h", "cStringIO.h", "graminit.h", "grammar.h",
- "longintrepr.h", "metagrammar.h",
- "node.h", "opcode.h", "osdefs.h", "pgenheaders.h",
- "py_curses.h", "parsetok.h", "symtable.h", "token.h"]
-
-
-def list_headers():
- """Return a list of headers."""
- incdir = os.path.join(srcdir, "Include")
- return [fn for fn in os.listdir(incdir)
- if fn.endswith(".h") and fn not in EXCLUDES]
-
-
-def matcher(pattern):
- return re.compile(pattern).match
-
-MATCHERS = [
- matcher(r"\\begin\{cfuncdesc\}\{[^{]*\}\{(?P<sym>[^{]*)\}"),
- matcher(r"\\cfuncline\{[^{]*\}\{(?P<sym>[^{]*)\}"),
- matcher(r"\\begin\{ctypedesc\}(\[[^{]*\])?\{(?P<sym>[^{]*)\}"),
- matcher(r"\\begin\{cvardesc\}\{[^{]*\}\{(?P<sym>[^{]*)\}"),
- matcher(r"\\begin\{cmemberdesc\}\{[^{]*\}\{(?P<sym>[^{]*)\}"),
- matcher(r"\\cmemberline\{[^{]*\}\{(?P<sym>[^{]*)\}"),
- matcher(r"\\begin\{csimplemacrodesc\}\{(?P<sym>[^{]*)\}"),
- ]
-
-
-def list_documented_items():
- """Return a list of everything that's already documented."""
- apidir = os.path.join(srcdir, "Doc", "api")
- files = [fn for fn in os.listdir(apidir) if fn.endswith(".tex")]
- L = []
- for fn in files:
- fullname = os.path.join(apidir, fn)
- for line in open(fullname):
- line = line.lstrip()
- if not line.startswith("\\"):
- continue
- for matcher in MATCHERS:
- m = matcher(line)
- if m:
- L.append(m.group("sym"))
- break
- return L
-
-def split_documented(all, documented):
- """Split the list of all symbols into documented and undocumented
- categories."""
- doc = []
- undoc = []
- for t in all:
- if t[0] in documented:
- doc.append(t)
- else:
- undoc.append(t)
- return doc, undoc
-
-def print_list(L, title=None):
- """Dump a list to stdout."""
- if title:
- print title + ":"
- print "-" * (len(title) + 1)
- w = 0
- for sym, filename in L:
- w = max(w, len(sym))
- if w % 4 == 0:
- w += 4
- else:
- w += (4 - (w % 4))
- for sym, filename in L:
- print "%-*s%s" % (w, sym, filename)
-
-
-_spcjoin = ' '.join
-
-def main():
- args = sys.argv[1:]
- if args:
- headers = args
- documented = []
- else:
- os.chdir(os.path.join(srcdir, "Include"))
- headers = list_headers()
- documented = list_documented_items()
-
- cmd = ("ctags -f - --file-scope=no --c-types=dgpstux "
- "-Istaticforward -Istatichere=static "
- + _spcjoin(headers))
- fp = os.popen(cmd)
- L = []
- prevsym = None
- while 1:
- line = fp.readline()
- if not line:
- break
- sym, filename = line.split()[:2]
- if sym == prevsym:
- continue
- if not sym.endswith("_H"):
- L.append((sym, filename))
- prevsym = sym
- L.sort()
- fp.close()
-
- try:
- if documented:
- documented, undocumented = split_documented(L, documented)
- print_list(documented, "Documented symbols")
- if undocumented:
- print
- print_list(undocumented, "Undocumented symbols")
- else:
- print_list(L)
- except IOError as e:
- if e.errno != errno.EPIPE:
- raise
-
-
-if __name__ == "__main__":
- main()
diff --git a/Doc/tools/findmodrefs b/Doc/tools/findmodrefs
deleted file mode 100755
index 8c5f93f..0000000
--- a/Doc/tools/findmodrefs
+++ /dev/null
@@ -1,63 +0,0 @@
-#! /usr/bin/env python
-# -*- Python -*-
-
-import fileinput
-import getopt
-import glob
-import os
-import re
-import sys
-
-
-declare_rx = re.compile(
- r"\\declaremodule(?:\[[a-zA-Z0-9]*\]*)?{[a-zA-Z_0-9]+}{([a-zA-Z_0-9]+)}")
-
-module_rx = re.compile(r"\\module{([a-zA-Z_0-9]+)}")
-
-def main():
- try:
- just_list = 0
- print_lineno = 0
- opts, args = getopt.getopt(sys.argv[1:], "ln", ["list", "number"])
- for opt, arg in opts:
- if opt in ("-l", "--list"):
- just_list = 1
- elif opt in ("-n", "--number"):
- print_lineno = 1
- files = args
- if not files:
- files = glob.glob("*.tex")
- files.sort()
- modulename = None
- for line in fileinput.input(files):
- if line[:9] == r"\section{":
- modulename = None
- continue
- if line[:16] == r"\modulesynopsys{":
- continue
- m = declare_rx.match(line)
- if m:
- modulename = m.group(1)
- continue
- if not modulename:
- continue
- m = module_rx.search(line)
- if m:
- name = m.group(1)
- if name != modulename:
- filename = fileinput.filename()
- if just_list:
- print filename
- fileinput.nextfile()
- modulename = None
- elif print_lineno:
- print "%s(%d):%s" \
- % (filename, fileinput.filelineno(), line[:-1])
- else:
- print "%s:%s" % (filename, line[:-1])
- except KeyboardInterrupt:
- sys.exit(1)
-
-
-if __name__ == "__main__":
- main()
diff --git a/Doc/tools/findsyms b/Doc/tools/findsyms
deleted file mode 100755
index 3b0f709..0000000
--- a/Doc/tools/findsyms
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/usr/bin/env python
-
-# Released to the public domain by Skip Montanaro, 28 March 2002
-
-"""
-findsyms.py - try to identify undocumented symbols exported by modules
-
-Usage: findsyms.py librefdir
-
-For each lib*.tex file in the libref manual source directory, identify which
-module is documented, import the module if possible, then search the LaTeX
-source for the symbols global to that module. Report any that don't seem to
-be documented.
-
-Certain exceptions are made to the list of undocumented symbols:
-
- * don't mention symbols in which all letters are upper case on the
- assumption they are manifest constants
-
- * don't mention symbols that are themselves modules
-
- * don't mention symbols that match those exported by os, math, string,
- types, or __builtin__ modules
-
-Finally, if a name is exported by the module but fails a getattr() lookup,
-that anomaly is reported.
-"""
-
-import __builtin__
-import getopt
-import glob
-import math
-import os
-import re
-import string
-import sys
-import types
-import warnings
-
-def usage():
- print >> sys.stderr, """
-usage: %s dir
-where 'dir' is the Library Reference Manual source directory.
-""" % os.path.basename(sys.argv[0])
-
-def main():
- try:
- opts, args = getopt.getopt(sys.argv[1:], "")
- except getopt.error:
- usage()
- return
-
- if not args:
- usage()
- return
-
- libdir = args[0]
-
- warnings.filterwarnings("error")
-
- pat = re.compile(r"\\declaremodule\s*{[^}]*}\s*{([^}]*)}")
-
- missing = []
- filelist = glob.glob(os.path.join(libdir, "lib*.tex"))
- filelist.sort()
- for f in filelist:
- mod = f[3:-4]
- if not mod: continue
- data = open(f).read()
- mods = re.findall(pat, data)
- if not mods:
- print "No module declarations found in", f
- continue
- for modname in mods:
- # skip special modules
- if modname.startswith("__"):
- continue
- try:
- mod = __import__(modname)
- except ImportError:
- missing.append(modname)
- continue
- except DeprecationWarning:
- print "Deprecated module:", modname
- continue
- if hasattr(mod, "__all__"):
- all = mod.__all__
- else:
- all = [k for k in dir(mod) if k[0] != "_"]
- mentioned = 0
- all.sort()
- for name in all:
- if data.find(name) == -1:
- # certain names are predominantly used for testing
- if name in ("main","test","_test"):
- continue
- # is it some sort of manifest constant?
- if name.upper() == name:
- continue
- try:
- item = getattr(mod, name)
- except AttributeError:
- print " ", name, "exposed, but not an attribute"
- continue
- # don't care about modules that might be exposed
- if type(item) == types.ModuleType:
- continue
- # check a few modules which tend to be import *'d
- isglobal = 0
- for m in (os, math, string, __builtin__, types):
- if hasattr(m, name) and item == getattr(m, name):
- isglobal = 1
- break
- if isglobal: continue
- if not mentioned:
- print "Not mentioned in", modname, "docs:"
- mentioned = 1
- print " ", name
- if missing:
- missing.sort()
- print "Could not import:"
- print " ", ", ".join(missing)
-
-if __name__ == "__main__":
- try:
- main()
- except KeyboardInterrupt:
- pass
diff --git a/Doc/tools/fix_hack b/Doc/tools/fix_hack
deleted file mode 100755
index 8dad111..0000000
--- a/Doc/tools/fix_hack
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-sed -e 's/{\\ptt[ ]*\\char[ ]*'"'"'137}/_/g' <"$1" > "@$1" && mv "@$1" $1
diff --git a/Doc/tools/fix_libaux.sed b/Doc/tools/fix_libaux.sed
deleted file mode 100755
index fb33cc5..0000000
--- a/Doc/tools/fix_libaux.sed
+++ /dev/null
@@ -1,3 +0,0 @@
-#! /bin/sed -f
-s/{\\tt \\hackscore {}\\hackscore {}/\\sectcode{__/
-s/\\hackscore {}\\hackscore {}/__/
diff --git a/Doc/tools/fixinfo.el b/Doc/tools/fixinfo.el
deleted file mode 100644
index 267a7e3..0000000
--- a/Doc/tools/fixinfo.el
+++ /dev/null
@@ -1,15 +0,0 @@
-(defun fix-python-texinfo ()
- (goto-char (point-min))
- (replace-regexp "\\(@setfilename \\)\\([-a-z]*\\)$"
- "\\1python-\\2.info")
- (replace-string "@node Front Matter\n@chapter Abstract\n"
- "@node Abstract\n@section Abstract\n")
- (mark-whole-buffer)
- (texinfo-master-menu 'update-all-nodes)
- (save-buffer)
- ) ;; fix-python-texinfo
-
-;; now really do it:
-(find-file (car command-line-args-left))
-(fix-python-texinfo)
-(kill-emacs)
diff --git a/Doc/tools/getpagecounts b/Doc/tools/getpagecounts
deleted file mode 100755
index 1adc470..0000000
--- a/Doc/tools/getpagecounts
+++ /dev/null
@@ -1,97 +0,0 @@
-#! /usr/bin/env python
-
-"""Generate a page count report of the PostScript version of the manuals."""
-
-__version__ = '$Revision$'
-
-import getopt
-import sys
-
-
-class PageCounter:
- def __init__(self):
- self.doclist = []
- self.total = 0
- self.title_width = 0
- self.version = ""
-
- def add_document(self, prefix, title):
- count = count_pages(prefix + ".ps")
- self.doclist.append((title, prefix, count))
- self.title_width = max(self.title_width, len(title))
- self.total = self.total + count
-
- def dump(self):
- fmt = "%%-%ds (%%s.ps, %%d pages)" % self.title_width
- for item in self.doclist:
- print fmt % item
- print
- print " Total page count: %d" % self.total
-
- def parse_options(self):
- opts, args = getopt.getopt(sys.argv[1:], "r:", ["release="])
- assert not args
- for opt, arg in opts:
- if opt in ("-r", "--release"):
- self.version = arg
-
- def run(self):
- self.parse_options()
- if self.version:
- version = self.version[:3]
- self.add_document("whatsnew" + version.replace(".", ""),
- "What's New in Python " + version)
- for prefix, title in [
- ("api", "Python/C API"),
- ("ext", "Extending and Embedding the Python Interpreter"),
- ("lib", "Python Library Reference"),
- ("mac", "Macintosh Module Reference"),
- ("ref", "Python Reference Manual"),
- ("tut", "Python Tutorial"),
- ("doc", "Documenting Python"),
- ("inst", "Installing Python Modules"),
- ("dist", "Distributing Python Modules"),
- ]:
- self.add_document(prefix, title)
- print self.PREFIX
- self.dump()
- print self.SUFFIX
-
- PREFIX = """\
-This is the PostScript version of the standard Python documentation.
-If you plan to print this, be aware that some of the documents are
-long. It is formatted for printing on two-sided paper; if you do plan
-to print this, *please* print two-sided if you have a printer capable
-of it! To locate published copies of the larger manuals, or other
-Python reference material, consult the Python Bookstore at:
-
- http://wiki.python.org/moin/PythonBooks
-
-The following manuals are included in this package:
-"""
- SUFFIX = """\
-
-
-If you have any questions, comments, or suggestions regarding these
-documents, please send them via email to docs@python.org.
-"""
-
-def count_pages(filename):
- fp = open(filename)
- count = 0
- while 1:
- lines = fp.readlines(1024*40)
- if not lines:
- break
- for line in lines:
- if line[:7] == "%%Page:":
- count = count + 1
- fp.close()
- return count
-
-
-def main():
- PageCounter().run()
-
-if __name__ == "__main__":
- main()
diff --git a/Doc/tools/getversioninfo b/Doc/tools/getversioninfo
deleted file mode 100755
index c1998d5..0000000
--- a/Doc/tools/getversioninfo
+++ /dev/null
@@ -1,71 +0,0 @@
-#! /usr/bin/env python
-
-import os
-import re
-import sys
-
-try:
- __file__
-except NameError:
- __file__ = sys.argv[0]
-
-tools = os.path.dirname(os.path.abspath(__file__))
-Doc = os.path.dirname(tools)
-src = os.path.dirname(Doc)
-patchlevel_h = os.path.join(src, "Include", "patchlevel.h")
-
-# This won't pick out all #defines, but it will pick up the ones we
-# care about.
-rx = re.compile(r"\s*#define\s+([a-zA-Z][a-zA-Z_0-9]*)\s+([a-zA-Z_0-9]+)")
-
-d = {}
-f = open(patchlevel_h)
-for line in f:
- m = rx.match(line)
- if m is not None:
- name, value = m.group(1, 2)
- d[name] = value
-f.close()
-
-release = "%s.%s" % (d["PY_MAJOR_VERSION"], d["PY_MINOR_VERSION"])
-micro = int(d["PY_MICRO_VERSION"])
-shortversion = release
-if micro != 0:
- release += "." + str(micro)
-level = d["PY_RELEASE_LEVEL"]
-
-suffixes = {
- "PY_RELEASE_LEVEL_ALPHA": "a",
- "PY_RELEASE_LEVEL_BETA": "b",
- "PY_RELEASE_LEVEL_GAMMA": "c",
- }
-
-releaseinfo = ""
-if level != "PY_RELEASE_LEVEL_FINAL":
- releaseinfo = suffixes[level] + str(int(d["PY_RELEASE_SERIAL"]))
-
-def write_file(name, text):
- """Write text to a file if the file doesn't exist or if text
- differs from any existing content."""
- if os.path.exists(name):
- f = open(name, "r")
- s = f.read()
- f.close()
- if s == text:
- return
- f = open(name, "w")
- f.write(text)
- f.close()
-
-patchlevel_tex = os.path.join(Doc, "commontex", "patchlevel.tex")
-
-write_file(patchlevel_tex,
- "%% This file is generated by ../tools/getversioninfo;\n"
- "%% do not edit manually.\n"
- "\n"
- "\\release{%s}\n"
- "\\setreleaseinfo{%s}\n"
- "\\setshortversion{%s}\n"
- % (release, releaseinfo, shortversion))
-
-print(release + releaseinfo)
diff --git a/Doc/tools/html2texi.pl b/Doc/tools/html2texi.pl
deleted file mode 100755
index 5dcfd46..0000000
--- a/Doc/tools/html2texi.pl
+++ /dev/null
@@ -1,1750 +0,0 @@
-#! /usr/bin/env perl
-# html2texi.pl -- Convert HTML documentation to Texinfo format
-# Michael Ernst <mernst@cs.washington.edu>
-# Time-stamp: <1999-01-12 21:34:27 mernst>
-
-# This program converts HTML documentation trees into Texinfo format.
-# Given the name of a main (or contents) HTML file, it processes that file,
-# and other files (transitively) referenced by it, into a Texinfo file
-# (whose name is chosen from the file or directory name of the argument).
-# For instance:
-# html2texi.pl api/index.html
-# produces file "api.texi".
-
-# Texinfo format can be easily converted to Info format (for browsing in
-# Emacs or the standalone Info browser), to a printed manual, or to HTML.
-# Thus, html2texi.pl permits conversion of HTML files to Info format, and
-# secondarily enables producing printed versions of Web page hierarchies.
-
-# Unlike HTML, Info format is searchable. Since Info is integrated into
-# Emacs, one can read documentation without starting a separate Web
-# browser. Additionally, Info browsers (including Emacs) contain
-# convenient features missing from Web browsers, such as easy index lookup
-# and mouse-free browsing.
-
-# Limitations:
-# html2texi.pl is currently tuned to latex2html output (and it corrects
-# several latex2html bugs), but should be extensible to arbitrary HTML
-# documents. It will be most useful for HTML with a hierarchical structure
-# and an index, and it recognizes those features as created by latex2html
-# (and possibly by some other tools). The HTML tree to be traversed must
-# be on local disk, rather than being accessed via HTTP.
-# This script requires the use of "checkargs.pm". To eliminate that
-# dependence, replace calls to check_args* by @_ (which is always the last
-# argument to those functions).
-# Also see the "to do" section, below.
-# Comments, suggestions, bug fixes, and enhancements are welcome.
-
-# Troubleshooting:
-# Malformed HTML can cause this program to abort, so
-# you should check your HTML files to make sure they are legal.
-
-
-###
-### Typical usage for the Python documentation:
-###
-
-# (Actually, most of this is in a Makefile instead.)
-# The resulting Info format Python documentation is currently available at
-# ftp://ftp.cs.washington.edu/homes/mernst/python-info.tar.gz
-
-# Fix up HTML problems, eg <DT><DL COMPACT><DD> should be <DT><DL COMPACT><DD>.
-
-# html2texi.pl /homes/fish/mernst/tmp/python-doc/html/api/index.html
-# html2texi.pl /homes/fish/mernst/tmp/python-doc/html/ext/index.html
-# html2texi.pl /homes/fish/mernst/tmp/python-doc/html/lib/index.html
-# html2texi.pl /homes/fish/mernst/tmp/python-doc/html/mac/index.html
-# html2texi.pl /homes/fish/mernst/tmp/python-doc/html/ref/index.html
-# html2texi.pl /homes/fish/mernst/tmp/python-doc/html/tut/index.html
-
-# Edit the generated .texi files:
-# * change @setfilename to prefix "python-"
-# * fix up any sectioning, such as for Abstract
-# * make Texinfo menus
-# * perhaps remove the @detailmenu ... @end detailmenu
-# In Emacs, to do all this:
-# (progn (goto-char (point-min)) (replace-regexp "\\(@setfilename \\)\\([-a-z]*\\)$" "\\1python-\\2.info") (replace-string "@node Front Matter\n@chapter Abstract\n" "@node Abstract\n@section Abstract\n") (progn (mark-whole-buffer) (texinfo-master-menu 'update-all-nodes)) (save-buffer))
-
-# makeinfo api.texi
-# makeinfo ext.texi
-# makeinfo lib.texi
-# makeinfo mac.texi
-# makeinfo ref.texi
-# makeinfo tut.texi
-
-
-###
-### Structure of the code
-###
-
-# To be written...
-
-
-###
-### Design decisions
-###
-
-# Source and destination languages
-# --------------------------------
-#
-# The goal is Info files; I create Texinfo, so I don't have to worry about
-# the finer details of Info file creation. (I'm not even sure of its exact
-# format.)
-#
-# Why not start from LaTeX rather than HTML?
-# I could hack latex2html itself to produce Texinfo instead, or fix up
-# partparse.py (which already translates LaTeX to Teinfo).
-# Pros:
-# * has high-level information such as index entries, original formatting
-# Cons:
-# * those programs are complicated to read and understand
-# * those programs try to handle arbitrary LaTeX input, track catcodes,
-# and more: I don't want to go to that effort. HTML isn't as powerful
-# as LaTeX, so there are fewer subtleties.
-# * the result wouldn't work for arbitrary HTML documents; it would be
-# nice to eventually extend this program to HTML produced from Docbook,
-# Frame, and more.
-
-# Parsing
-# -------
-#
-# I don't want to view the text as a linear stream; I'd rather parse the
-# whole thing and then do pattern matching over the parsed representation (to
-# find idioms such as indices, lists of child nodes, etc.).
-# * Perl provides HTML::TreeBuilder, which does just what I want.
-# * libwww-perl: http://www.linpro.no/lwp/
-# * TreeBuilder: HTML-Tree-0.51.tar.gz
-# * Python Parsers, Formatters, and Writers don't really provide the right
-# interface (and the version in Grail doesn't correspond to another
-# distributed version, so I'm confused about which to be using). I could
-# write something in Python that creates a parse tree, but why bother?
-
-# Other implementation language issues:
-# * Python lacks variable declarations, reasonable scoping, and static
-# checking tools. I've written some of the latter for myself that make
-# my Perl programming a lot safer than my Python programming will be until
-# I have a similar suite for that language.
-
-
-###########################################################################
-### To do
-###
-
-# Section names:
-# Fix the problem with multiple sections in a single file (eg, Abstract in
-# Front Matter section).
-# Deal with cross-references, as in /homes/fish/mernst/tmp/python-doc/html/ref/types.html:310
-# Index:
-# Perhaps double-check that every tag mentioned in the index is found
-# in the text.
-# Python: email to docs@python.org, to get their feedback.
-# Compare to existing lib/ Info manual
-# Write the hooks into info-look; replace pyliblookup1-1.tar.gz.
-# Postpass to remove extra quotation marks around typography already in
-# a different font (to avoid double delimiters as in "`code'"); or
-# perhaps consider using only font-based markup so that we don't get
-# the extra *bold* and `code' markup in Info.
-
-## Perhaps don't rely on automatic means for adding up, next, prev; I have
-## all that info available to me already, so it's not so much trouble to
-## add it. (Right?) But it is *so* easy to use Emacs instead...
-
-
-###########################################################################
-### Strictures
-###
-
-# man HTML::TreeBuilder
-# man HTML::Parser
-# man HTML::Element
-
-# require HTML::ParserWComment;
-require HTML::Parser;
-require HTML::TreeBuilder;
-require HTML::Element;
-
-use File::Basename;
-
-use strict;
-# use Carp;
-
-use checkargs;
-
-
-###########################################################################
-### Variables
-###
-
-my @section_stack = (); # elements are chapter/section/subsec nodetitles (I think)
-my $current_ref_tdf; # for the file currently being processed;
- # used in error messages
-my $html_directory;
-my %footnotes;
-
-# First element should not be used.
-my @sectionmarker = ("manual", "chapter", "section", "subsection", "subsubsection");
-
-my %inline_markup = ("b" => "strong",
- "code" => "code",
- "i" => "emph",
- "kbd" => "kbd",
- "samp" => "samp",
- "strong" => "strong",
- "tt" => "code",
- "var" => "var");
-
-my @deferred_index_entries = ();
-
-my @index_titles = (); # list of (filename, type) lists
-my %index_info = ("Index" => ["\@blindex", "bl"],
- "Concept Index" => ["\@cindex", "cp"],
- "Module Index" => ["\@mdindex", "md"]);
-
-
-###########################################################################
-### Main/contents page
-###
-
-# Process first-level page on its own, or just a contents page? Well, I do
-# want the title, author, etc., and the front matter... For now, just add
-# that by hand at the end.
-
-
-# data structure possibilities:
-# * tree-like (need some kind of stack when processing (or parent pointers))
-# * list of name and depth; remember old and new depths.
-
-# Each element is a reference to a list of (nodetitle, depth, filename).
-my @contents_list = ();
-
-# The problem with doing fixups on the fly is that some sections may have
-# already been processed (and no longer available) by the time we notice
-# others with the same name. It's probably better to fully construct the
-# contents list (reading in all files of interest) upfront; that will also
-# let me do a better job with cross-references, because again, all files
-# will already be read in.
-my %contents_hash = ();
-my %contents_fixups = ();
-
-my @current_contents_list = ();
-
-# Merge @current_contents_list into @contents_list,
-# and set @current_contents_list to be empty.
-sub merge_contents_lists ( )
-{ check_args(0, @_);
-
- # Three possibilities:
- # * @contents_list is empty: replace it by @current_contents_list.
- # * prefixes of the two lists are identical: do nothing
- # * @current_contents_list is all at lower level than $contents_list[0];
- # prefix @contents_list by @current_contents_list
-
- if (scalar(@current_contents_list) == 0)
- { die "empty current_contents_list"; }
-
- # if (scalar(@contents_list) == 0)
- # { @contents_list = @current_contents_list;
- # @current_contents_list = ();
- # return; }
-
- # if (($ {$contents_list[0]}[1]) < ($ {$current_contents_list[0]}[1]))
- # { unshift @contents_list, @current_contents_list;
- # @current_contents_list = ();
- # return; }
-
- for (my $i=0; $i<scalar(@current_contents_list); $i++)
- { my $ref_c_tdf = $current_contents_list[$i];
- if ($i >= scalar(@contents_list))
- { push @contents_list, $ref_c_tdf;
- my $title = $ {$ref_c_tdf}[0];
- if (defined $contents_hash{$title})
- { $contents_fixups{$title} = 1; }
- else
- { $contents_hash{$title} = 1; }
- next; }
- my $ref_tdf = $contents_list[$i];
- my ($title, $depth, $file) = @{$ref_tdf};
- my ($c_title, $c_depth, $c_file) = @{$ref_c_tdf};
-
- if (($title ne $c_title)
- && ($depth < $c_depth)
- && ($file ne $c_file))
- { splice @contents_list, $i, 0, $ref_c_tdf;
- if (defined $contents_hash{$c_title})
- { $contents_fixups{$c_title} = 1; }
- else
- { $contents_hash{$c_title} = 1; }
- next; }
-
- if (($title ne $c_title)
- || ($depth != $c_depth)
- || ($file ne $c_file))
- { die ("while processing $ {$current_ref_tdf}[2] at depth $ {$current_ref_tdf}[1], mismatch at index $i:",
- "\n main: <<<$title>>> $depth $file",
- "\n curr: <<<$c_title>>> $c_depth $c_file"); }
- }
- @current_contents_list = ();
-}
-
-
-
-# Set @current_contents_list to a list of (title, href, sectionlevel);
-# then merge that list into @contents_list.
-# Maybe this function should also produce a map
-# from title (or href) to sectionlevel (eg "chapter"?).
-sub process_child_links ( $ )
-{ my ($he) = check_args(1, @_);
-
- # $he->dump();
- if (scalar(@current_contents_list) != 0)
- { die "current_contents_list nonempty: @current_contents_list"; }
- $he->traverse(\&increment_current_contents_list, 'ignore text');
-
- # Normalize the depths; for instance, convert 1,3,5 into 0,1,2.
- my %depths = ();
- for my $ref_tdf (@current_contents_list)
- { $depths{$ {$ref_tdf}[1]} = 1; }
- my @sorted_depths = sort keys %depths;
- my $current_depth = scalar(@section_stack)-1;
- my $current_depth_2 = $ {$current_ref_tdf}[1];
- if ($current_depth != $current_depth_2)
- { die "mismatch in current depths: $current_depth $current_depth_2; ", join(", ", @section_stack); }
- for (my $i=0; $i<scalar(@sorted_depths); $i++)
- { $depths{$sorted_depths[$i]} = $i + $current_depth+1; }
- for my $ref_tdf (@current_contents_list)
- { $ {$ref_tdf}[1] = $depths{$ {$ref_tdf}[1]}; }
-
- # Eliminate uninteresting sections. Hard-coded hack for now.
- if ($ {$current_contents_list[-1]}[0] eq "About this document ...")
- { pop @current_contents_list; }
- if ((scalar(@current_contents_list) > 1)
- && ($ {$current_contents_list[1]}[0] eq "Contents"))
- { my $ref_first_tdf = shift @current_contents_list;
- $current_contents_list[0] = $ref_first_tdf; }
-
- for (my $i=0; $i<scalar(@current_contents_list); $i++)
- { my $ref_tdf = $current_contents_list[$i];
- my $title = $ {$ref_tdf}[0];
- if (exists $index_info{$title})
- { my $index_file = $ {$ref_tdf}[2];
- my ($indexing_command, $suffix) = @{$index_info{$title}};
- process_index_file($index_file, $indexing_command);
- print TEXI "\n\@defindex $suffix\n";
- push @index_titles, $title;
- splice @current_contents_list, $i, 1;
- $i--; }
- elsif ($title =~ /\bIndex$/)
- { print STDERR "Warning: \"$title\" might be an index; if so, edit \%index_info.\n"; } }
-
- merge_contents_lists();
-
- # print_contents_list();
- # print_index_info();
-}
-
-
-sub increment_current_contents_list ( $$$ )
-{ my ($he, $startflag, $depth) = check_args(3, @_);
- if (!$startflag)
- { return; }
-
- if ($he->tag eq "li")
- { my @li_content = @{$he->content};
- if ($li_content[0]->tag ne "a")
- { die "first element of <LI> should be <A>"; }
- my ($name, $href, @content) = anchor_info($li_content[0]);
- # unused $name
- my $title = join("", collect_texts($li_content[0]));
- $title = texi_remove_punctuation($title);
- # The problem with these is that they are formatted differently in
- # @menu and @node!
- $title =~ s/``/\"/g;
- $title =~ s/''/\"/g;
- $title =~ s/ -- / /g;
- push @current_contents_list, [ $title, $depth, $href ]; }
- return 1;
-}
-
-# Simple version for section titles
-sub html_to_texi ( $ )
-{ my ($he) = check_args(1, @_);
- if (!ref $he)
- { return $he; }
-
- my $tag = $he->tag;
- if (exists $inline_markup{$tag})
- { my $result = "\@$inline_markup{$tag}\{";
- for my $elt (@{$he->content})
- { $result .= html_to_texi($elt); }
- $result .= "\}";
- return $result; }
- else
- { $he->dump();
- die "html_to_texi confused by <$tag>"; }
-}
-
-
-
-sub print_contents_list ()
-{ check_args(0, @_);
- print STDERR "Contents list:\n";
- for my $ref_tdf (@contents_list)
- { my ($title, $depth, $file) = @{$ref_tdf};
- print STDERR "$title $depth $file\n"; }
-}
-
-
-
-###########################################################################
-### Index
-###
-
-my $l2h_broken_link_name = "l2h-";
-
-
-# map from file to (map from anchor name to (list of index texts))
-# (The list is needed when a single LaTeX command like \envvar
-# expands to multiple \index commands.)
-my %file_index_entries = ();
-my %this_index_entries; # map from anchor name to (list of index texts)
-
-my %file_index_entries_broken = (); # map from file to (list of index texts)
-my @this_index_entries_broken;
-
-my $index_prefix = "";
-my @index_prefixes = ();
-
-my $this_indexing_command;
-
-sub print_index_info ()
-{ check_args(0, @_);
- my ($key, $val);
- for my $file (sort keys %file_index_entries)
- { my %index_entries = %{$file_index_entries{$file}};
- print STDERR "file: $file\n";
- for my $aname (sort keys %index_entries)
- { my @entries = @{$index_entries{$aname}};
- if (scalar(@entries) == 1)
- { print STDERR " $aname : $entries[0]\n"; }
- else
- { print STDERR " $aname : ", join("\n " . (" " x length($aname)), @entries), "\n"; } } }
- for my $file (sort keys %file_index_entries_broken)
- { my @entries = @{$file_index_entries_broken{$file}};
- print STDERR "file: $file\n";
- for my $entry (@entries)
- { print STDERR " $entry\n"; }
- }
-}
-
-
-sub process_index_file ( $$ )
-{ my ($file, $indexing_command) = check_args(2, @_);
- # print "process_index_file $file $indexing_command\n";
-
- my $he = file_to_tree($html_directory . $file);
- # $he->dump();
-
- $this_indexing_command = $indexing_command;
- $he->traverse(\&process_if_index_dl_compact, 'ignore text');
- undef $this_indexing_command;
- # print "process_index_file done\n";
-}
-
-
-sub process_if_index_dl_compact ( $$$ )
-{ my ($he, $startflag) = (check_args(3, @_))[0,1]; # ignore depth argument
- if (!$startflag)
- { return; }
-
- if (($he->tag() eq "dl") && (defined $he->attr('compact')))
- { process_index_dl_compact($he);
- return 0; }
- else
- { return 1; }
-}
-
-
-# The elements of a <DL COMPACT> list from a LaTeX2HTML index:
-# * a single space: text to be ignored
-# * <DT> elements with an optional <DD> element following each one
-# Two types of <DT> elements:
-# * Followed by a <DD> element: the <DT> contains a single
-# string, and the <DD> contains a whitespace string to be ignored, a
-# <DL COMPACT> to be recursively processed (with the <DT> string as a
-# prefix), and a whitespace string to be ignored.
-# * Not followed by a <DD> element: contains a list of anchors
-# and texts (ignore the texts, which are only whitespace and commas).
-# Optionally contains a <DL COMPACT> to be recursively processed (with
-# the <DT> string as a prefix)
-sub process_index_dl_compact ( $ )
-{ my ($h) = check_args(1, @_);
- my @content = @{$h->content()};
- for (my $i = 0; $i < scalar(@content); $i++)
- { my $this_he = $content[$i];
- if ($this_he->tag ne "dt")
- { $this_he->dump();
- die "Expected <DT> tag: " . $this_he->tag; }
- if (($i < scalar(@content) - 1) && ($content[$i+1]->tag eq "dd"))
- { process_index_dt_and_dd($this_he, $content[$i+1]);
- $i++; }
- else
- { process_index_lone_dt($this_he); } } }
-
-
-
-# Argument is a <DT> element. If it contains more than one anchor, then
-# the texts of all subsequent ones are "[Link]". Example:
-# <DT>
-# <A HREF="embedding.html#l2h-201">
-# "$PATH"
-# ", "
-# <A HREF="embedding.html#l2h-205">
-# "[Link]"
-# Optionally contains a <DL COMPACT> as well. Example:
-# <DT>
-# <A HREF="types.html#l2h-616">
-# "attribute"
-# <DL COMPACT>
-# <DT>
-# <A HREF="assignment.html#l2h-3074">
-# "assignment"
-# ", "
-# <A HREF="assignment.html#l2h-3099">
-# "[Link]"
-# <DT>
-# <A HREF="types.html#l2h-">
-# "assignment, class"
-
-sub process_index_lone_dt ( $ )
-{ my ($dt) = check_args(1, @_);
- my @dtcontent = @{$dt->content()};
- my $acontent;
- my $acontent_suffix;
- for my $a (@dtcontent)
- { if ($a eq ", ")
- { next; }
- if (!ref $a)
- { $dt->dump;
- die "Unexpected <DT> string element: $a"; }
-
- if ($a->tag eq "dl")
- { push @index_prefixes, $index_prefix;
- if (!defined $acontent_suffix)
- { die "acontent_suffix not yet defined"; }
- $index_prefix .= $acontent_suffix . ", ";
- process_index_dl_compact($a);
- $index_prefix = pop(@index_prefixes);
- return; }
-
- if ($a->tag ne "a")
- { $dt->dump;
- $a->dump;
- die "Expected anchor in lone <DT>"; }
-
- my ($aname, $ahref, @acontent) = anchor_info($a);
- # unused $aname
- if (scalar(@acontent) != 1)
- { die "Expected just one content of <A> in <DT>: @acontent"; }
- if (ref $acontent[0])
- { $acontent[0]->dump;
- die "Expected string content of <A> in <DT>: $acontent[0]"; }
- if (!defined($acontent))
- { $acontent = $index_prefix . $acontent[0];
- $acontent_suffix = $acontent[0]; }
- elsif (($acontent[0] ne "[Link]") && ($acontent ne ($index_prefix . $acontent[0])))
- { die "Differing content: <<<$acontent>>>, <<<$acontent[0]>>>"; }
-
- if (!defined $ahref)
- { $dt->dump;
- die "no HREF in nachor in <DT>"; }
- my ($ahref_file, $ahref_name) = split(/\#/, $ahref);
- if (!defined $ahref_name)
- { # Reference to entire file
- $ahref_name = ""; }
-
- if ($ahref_name eq $l2h_broken_link_name)
- { if (!exists $file_index_entries_broken{$ahref_file})
- { $file_index_entries_broken{$ahref_file} = []; }
- push @{$file_index_entries_broken{$ahref_file}}, "$this_indexing_command $acontent";
- next; }
-
- if (!exists $file_index_entries{$ahref_file})
- { $file_index_entries{$ahref_file} = {}; }
- # Don't do this! It appears to make a copy, which is not desired.
- # my %index_entries = %{$file_index_entries{$ahref_file}};
- if (!exists $ {$file_index_entries{$ahref_file}}{$ahref_name})
- { $ {$file_index_entries{$ahref_file}}{$ahref_name} = []; }
- # { my $oldcontent = $ {$file_index_entries{$ahref_file}}{$ahref_name};
- # if ($acontent eq $oldcontent)
- # { die "Multiple identical index entries?"; }
- # die "Trying to add $acontent, but already have index entry pointing at $ahref_file\#$ahref_name: ${$file_index_entries{$ahref_file}}{$ahref_name}"; }
-
- push @{$ {$file_index_entries{$ahref_file}}{$ahref_name}}, "$this_indexing_command $acontent";
- # print STDERR "keys: ", keys %{$file_index_entries{$ahref_file}}, "\n";
- }
-}
-
-sub process_index_dt_and_dd ( $$ )
-{ my ($dt, $dd) = check_args(2, @_);
- my $dtcontent;
- { my @dtcontent = @{$dt->content()};
- if ((scalar(@dtcontent) != 1) || (ref $dtcontent[0]))
- { $dd->dump;
- $dt->dump;
- die "Expected single string (actual size = " . scalar(@dtcontent) . ") in content of <DT>: @dtcontent"; }
- $dtcontent = $dtcontent[0];
- $dtcontent =~ s/ +$//; }
- my $ddcontent;
- { my @ddcontent = @{$dd->content()};
- if (scalar(@ddcontent) != 1)
- { die "Expected single <DD> content, got ", scalar(@ddcontent), " elements:\n", join("\n", @ddcontent), "\n "; }
- $ddcontent = $ddcontent[0]; }
- if ($ddcontent->tag ne "dl")
- { die "Expected <DL> as content of <DD>, but saw: $ddcontent"; }
-
- push @index_prefixes, $index_prefix;
- $index_prefix .= $dtcontent . ", ";
- process_index_dl_compact($ddcontent);
- $index_prefix = pop(@index_prefixes);
-}
-
-
-###########################################################################
-### Ordinary sections
-###
-
-sub process_section_file ( $$$ )
-{ my ($file, $depth, $nodetitle) = check_args(3, @_);
- my $he = file_to_tree(($file =~ /^\//) ? $file : $html_directory . $file);
-
- # print STDERR "process_section_file: $file $depth $nodetitle\n";
-
- # Equivalently:
- # while ($depth >= scalar(@section_stack)) { pop(@section_stack); }
- @section_stack = @section_stack[0..$depth-1];
-
- # Not a great nodename fixup scheme; need a more global view
- if ((defined $contents_fixups{$nodetitle})
- && (scalar(@section_stack) > 0))
- { my $up_title = $section_stack[$#section_stack];
- # hack for Python Standard Library
- $up_title =~ s/^(Built-in|Standard) Module //g;
- my ($up_first_word) = split(/ /, $up_title);
- $nodetitle = "$up_first_word $nodetitle";
- }
-
- push @section_stack, $nodetitle;
- # print STDERR "new section_stack: ", join(", ", @section_stack), "\n";
-
- $he->traverse(\&process_if_child_links, 'ignore text');
- %footnotes = ();
- # $he->dump;
- $he->traverse(\&process_if_footnotes, 'ignore text');
-
- # $he->dump;
-
- if (exists $file_index_entries{$file})
- { %this_index_entries = %{$file_index_entries{$file}};
- # print STDERR "this_index_entries:\n ", join("\n ", keys %this_index_entries), "\n";
- }
- else
- { # print STDERR "Warning: no index entries for file $file\n";
- %this_index_entries = (); }
-
- if (exists $file_index_entries_broken{$file})
- { @this_index_entries_broken = @{$file_index_entries_broken{$file}}; }
- else
- { # print STDERR "Warning: no index entries for file $file\n";
- @this_index_entries_broken = (); }
-
-
- if ($he->tag() ne "html")
- { die "Expected <HTML> at top level"; }
- my @content = @{$he->content()};
- if ((!ref $content[0]) or ($content[0]->tag ne "head"))
- { $he->dump;
- die "<HEAD> not first element of <HTML>"; }
- if ((!ref $content[1]) or ($content[1]->tag ne "body"))
- { $he->dump;
- die "<BODY> not second element of <HTML>"; }
-
- $content[1]->traverse(\&output_body);
-}
-
-# stack of things we're inside that are preventing indexing from occurring now.
-# These are "h1", "h2", "h3", "h4", "h5", "h6", "dt" (and possibly others?)
-my @index_deferrers = ();
-
-sub push_or_pop_index_deferrers ( $$ )
-{ my ($tag, $startflag) = check_args(2, @_);
- if ($startflag)
- { push @index_deferrers, $tag; }
- else
- { my $old_deferrer = pop @index_deferrers;
- if ($tag ne $old_deferrer)
- { die "Expected $tag at top of index_deferrers but saw $old_deferrer; remainder = ", join(" ", @index_deferrers); }
- do_deferred_index_entries(); }
-}
-
-
-sub label_add_index_entries ( $;$ )
-{ my ($label, $he) = check_args_range(1, 2, @_);
- # print ((exists $this_index_entries{$label}) ? "*" : " "), " label_add_index_entries $label\n";
- # $he is the anchor element
- if (exists $this_index_entries{$label})
- { push @deferred_index_entries, @{$this_index_entries{$label}};
- return; }
-
- if ($label eq $l2h_broken_link_name)
- { # Try to find some text to use in guessing which links should point here
- # I should probably only look at the previous element, or if that is
- # all punctuation, the one before it; collecting all the previous texts
- # is a bit of overkill.
- my @anchor_texts = collect_texts($he);
- my @previous_texts = collect_texts($he->parent, $he);
- # 4 elements is arbitrary; ought to filter out punctuation and small words
- # first, then perhaps keep fewer. Perhaps also filter out formatting so
- # that we can see a larger chunk of text? (Probably not.)
- # Also perhaps should do further chunking into words, in case the
- # index term isn't a chunk of its own (eg, was in <tt>...</tt>.
- my @candidate_texts = (@anchor_texts, (reverse(@previous_texts))[0..min(3,$#previous_texts)]);
-
- my $guessed = 0;
- for my $text (@candidate_texts)
- { # my $orig_text = $text;
- if ($text =~ /^[\"\`\'().?! ]*$/)
- { next; }
- if (length($text) <= 2)
- { next; }
- # hack for Python manual; maybe defer until failure first time around?
- $text =~ s/^sys\.//g;
- for my $iterm (@this_index_entries_broken)
- { # I could test for zero: LaTeX2HTML's failures in the Python
- # documentation are only for items of the form "... (built-in...)"
- if (index($iterm, $text) != -1)
- { push @deferred_index_entries, $iterm;
- # print STDERR "Guessing index term `$iterm' for text `$orig_text'\n";
- $guessed = 1;
- } } }
- if (!$guessed)
- { # print STDERR "No guess in `", join("'; `", @this_index_entries_broken), "' for texts:\n `", join("'\n `", @candidate_texts), "'\n";
- }
- }
-}
-
-
-# Need to add calls to this at various places.
-# Perhaps add HTML::Element argument and do the check for appropriateness
-# here (ie, no action if inside <H1>, etc.).
-sub do_deferred_index_entries ()
-{ check_args(0, @_);
- if ((scalar(@deferred_index_entries) > 0)
- && (scalar(@index_deferrers) == 0))
- { print TEXI "\n", join("\n", @deferred_index_entries), "\n";
- @deferred_index_entries = (); }
-}
-
-my $table_columns; # undefined if not in a table
-my $table_first_column; # boolean
-
-sub output_body ( $$$ )
-{ my ($he, $startflag) = (check_args(3, @_))[0,1]; # ignore depth argument
-
- if (!ref $he)
- { my $space_index = index($he, " ");
- if ($space_index != -1)
- { # Why does
- # print TEXI texi_quote(substr($he, 0, $space_index+1));
- # give: Can't locate object method "TEXI" via package "texi_quote"
- # (Because the definition texi_quote hasn't been seen yet.)
- print TEXI &texi_quote(substr($he, 0, $space_index+1));
- do_deferred_index_entries();
- print TEXI &texi_quote(substr($he, $space_index+1)); }
- else
- { print TEXI &texi_quote($he); }
- return; }
-
- my $tag = $he->tag();
-
- # Ordinary text markup first
- if (exists $inline_markup{$tag})
- { if ($startflag)
- { print TEXI "\@$inline_markup{$tag}\{"; }
- else
- { print TEXI "\}"; } }
- elsif ($tag eq "a")
- { my ($name, $href, @content) = anchor_info($he);
- if (!$href)
- { # This anchor is only here for indexing/cross referencing purposes.
- if ($startflag)
- { label_add_index_entries($name, $he); }
- }
- elsif ($href =~ "^(ftp|http|news):")
- { if ($startflag)
- { # Should avoid second argument if it's identical to the URL.
- print TEXI "\@uref\{$href, "; }
- else
- { print TEXI "\}"; }
- }
- elsif ($href =~ /^\#(foot[0-9]+)$/)
- { # Footnote
- if ($startflag)
- { # Could double-check name and content, but I'm not
- # currently storing that information.
- print TEXI "\@footnote\{";
- $footnotes{$1}->traverse(\&output_body);
- print TEXI "\}";
- return 0; } }
- else
- { if ($startflag)
- { # cross-references are not active Info links, but no text is lost
- print STDERR "Can't deal with internal HREF anchors yet:\n";
- $he->dump; }
- }
- }
- elsif ($tag eq "br")
- { print TEXI "\@\n"; }
- elsif ($tag eq "body")
- { }
- elsif ($tag eq "center")
- { if (has_single_content_string($he)
- && ($ {$he->content}[0] =~ /^ *$/))
- { return 0; }
- if ($startflag)
- { print TEXI "\n\@center\n"; }
- else
- { print TEXI "\n\@end center\n"; }
- }
- elsif ($tag eq "div")
- { my $align = $he->attr('align');
- if (defined($align) && ($align eq "center"))
- { if (has_single_content_string($he)
- && ($ {$he->content}[0] =~ /^ *$/))
- { return 0; }
- if ($startflag)
- { print TEXI "\n\@center\n"; }
- else
- { print TEXI "\n\@end center\n"; } }
- }
- elsif ($tag eq "dl")
- { # Recognize "<dl><dd><pre> ... </pre></dl>" paradigm for "@example"
- if (has_single_content_with_tag($he, "dd"))
- { my $he_dd = $ {$he->content}[0];
- if (has_single_content_with_tag($he_dd, "pre"))
- { my $he_pre = $ {$he_dd->content}[0];
- print_pre($he_pre);
- return 0; } }
- if ($startflag)
- { # Could examine the elements, to be cleverer about formatting.
- # (Also to use ftable, vtable...)
- print TEXI "\n\@table \@asis\n"; }
- else
- { print TEXI "\n\@end table\n"; }
- }
- elsif ($tag eq "dt")
- { push_or_pop_index_deferrers($tag, $startflag);
- if ($startflag)
- { print TEXI "\n\@item "; }
- else
- { } }
- elsif ($tag eq "dd")
- { if ($startflag)
- { print TEXI "\n"; }
- else
- { }
- if (scalar(@index_deferrers) != 0)
- { $he->dump;
- die "Unexpected <$tag> while inside: (" . join(" ", @index_deferrers) . "); bad HTML?"; }
- do_deferred_index_entries();
- }
- elsif ($tag =~ /^(font|big|small)$/)
- { # Do nothing for now.
- }
- elsif ($tag =~ /^h[1-6]$/)
- { # We don't need this because we never recursively enter the heading content.
- # push_or_pop_index_deferrers($tag, $startflag);
- my $secname = "";
- my @seclabels = ();
- for my $elt (@{$he->content})
- { if (!ref $elt)
- { $secname .= $elt; }
- elsif ($elt->tag eq "br")
- { }
- elsif ($elt->tag eq "a")
- { my ($name, $href, @acontent) = anchor_info($elt);
- if ($href)
- { $he->dump;
- $elt->dump;
- die "Nonsimple anchor in <$tag>"; }
- if (!defined $name)
- { die "No NAME for anchor in $tag"; }
- push @seclabels, $name;
- for my $subelt (@acontent)
- { $secname .= html_to_texi($subelt); } }
- else
- { $secname .= html_to_texi($elt); } }
- if ($secname eq "")
- { die "No section name in <$tag>"; }
- if (scalar(@section_stack) == 1)
- { if ($section_stack[-1] ne "Top")
- { die "Not top? $section_stack[-1]"; }
- print TEXI "\@settitle $secname\n";
- print TEXI "\@c %**end of header\n";
- print TEXI "\n";
- print TEXI "\@node Top\n";
- print TEXI "\n"; }
- else
- { print TEXI "\n\@node $section_stack[-1]\n";
- print TEXI "\@$sectionmarker[scalar(@section_stack)-1] ", texi_remove_punctuation($secname), "\n"; }
- for my $seclabel (@seclabels)
- { label_add_index_entries($seclabel); }
- # This should only happen once per file.
- label_add_index_entries("");
- if (scalar(@index_deferrers) != 0)
- { $he->dump;
- die "Unexpected <$tag> while inside: (" . join(" ", @index_deferrers) . "); bad HTML?"; }
- do_deferred_index_entries();
- return 0;
- }
- elsif ($tag eq "hr")
- { }
- elsif ($tag eq "ignore")
- { # Hack for ignored elements
- return 0;
- }
- elsif ($tag eq "li")
- { if ($startflag)
- { print TEXI "\n\n\@item\n";
- do_deferred_index_entries(); } }
- elsif ($tag eq "ol")
- { if ($startflag)
- { print TEXI "\n\@enumerate \@bullet\n"; }
- else
- { print TEXI "\n\@end enumerate\n"; } }
- elsif ($tag eq "p")
- { if ($startflag)
- { print TEXI "\n\n"; }
- if (scalar(@index_deferrers) != 0)
- { $he->dump;
- die "Unexpected <$tag> while inside: (" . join(" ", @index_deferrers) . "); bad HTML?"; }
- do_deferred_index_entries(); }
- elsif ($tag eq "pre")
- { print_pre($he);
- return 0; }
- elsif ($tag eq "table")
- { # Could also indicate common formatting for first column, or
- # determine relative widths for columns (or determine a prototype row)
- if ($startflag)
- { if (defined $table_columns)
- { $he->dump;
- die "Can't deal with table nested inside $table_columns-column table"; }
- $table_columns = table_columns($he);
- if ($table_columns < 2)
- { $he->dump;
- die "Column with $table_columns columns?"; }
- elsif ($table_columns == 2)
- { print TEXI "\n\@table \@asis\n"; }
- else
- { print TEXI "\n\@multitable \@columnfractions";
- for (my $i=0; $i<$table_columns; $i++)
- { print TEXI " ", 1.0/$table_columns; }
- print TEXI "\n"; } }
- else
- { if ($table_columns == 2)
- { print TEXI "\n\@end table\n"; }
- else
- { print TEXI "\n\@end multitable\n"; }
- undef $table_columns; } }
- elsif (($tag eq "td") || ($tag eq "th"))
- { if ($startflag)
- { if ($table_first_column)
- { print TEXI "\n\@item ";
- $table_first_column = 0; }
- elsif ($table_columns > 2)
- { print TEXI "\n\@tab "; } }
- else
- { print TEXI "\n"; } }
- elsif ($tag eq "tr")
- { if ($startflag)
- { $table_first_column = 1; } }
- elsif ($tag eq "ul")
- { if ($startflag)
- { print TEXI "\n\@itemize \@bullet\n"; }
- else
- { print TEXI "\n\@end itemize\n"; } }
- else
- { # I used to have a newline before "output_body" here.
- print STDERR "output_body: ignoring <$tag> tag\n";
- $he->dump;
- return 0; }
-
- return 1;
-}
-
-sub print_pre ( $ )
-{ my ($he_pre) = check_args(1, @_);
- if (!has_single_content_string($he_pre))
- { die "Multiple or non-string content for <PRE>: ", @{$he_pre->content}; }
- my $pre_content = $ {$he_pre->content}[0];
- print TEXI "\n\@example";
- print TEXI &texi_quote($pre_content);
- print TEXI "\@end example\n";
-}
-
-sub table_columns ( $ )
-{ my ($table) = check_args(1, @_);
- my $result = 0;
- for my $row (@{$table->content})
- { if ($row->tag ne "tr")
- { $table->dump;
- $row->dump;
- die "Expected <TR> as table row."; }
- $result = max($result, scalar(@{$row->content})); }
- return $result;
-}
-
-
-###########################################################################
-### Utilities
-###
-
-sub min ( $$ )
-{ my ($x, $y) = check_args(2, @_);
- return ($x < $y) ? $x : $y;
-}
-
-sub max ( $$ )
-{ my ($x, $y) = check_args(2, @_);
- return ($x > $y) ? $x : $y;
-}
-
-sub file_to_tree ( $ )
-{ my ($file) = check_args(1, @_);
-
- my $tree = new HTML::TreeBuilder;
- $tree->ignore_unknown(1);
- # $tree->warn(1);
- $tree->parse_file($file);
- cleanup_parse_tree($tree);
- return $tree
-}
-
-
-sub has_single_content ( $ )
-{ my ($he) = check_args(1, @_);
- if (!ref $he)
- { # return 0;
- die "Non-reference argument: $he"; }
- my $ref_content = $he->content;
- if (!defined $ref_content)
- { return 0; }
- my @content = @{$ref_content};
- if (scalar(@content) != 1)
- { return 0; }
- return 1;
-}
-
-
-# Return true if the content of the element contains only one element itself,
-# and that inner element has the specified tag.
-sub has_single_content_with_tag ( $$ )
-{ my ($he, $tag) = check_args(2, @_);
- if (!has_single_content($he))
- { return 0; }
- my $content = $ {$he->content}[0];
- if (!ref $content)
- { return 0; }
- my $content_tag = $content->tag;
- if (!defined $content_tag)
- { return 0; }
- return $content_tag eq $tag;
-}
-
-sub has_single_content_string ( $ )
-{ my ($he) = check_args(1, @_);
- if (!has_single_content($he))
- { return 0; }
- my $content = $ {$he->content}[0];
- if (ref $content)
- { return 0; }
- return 1;
-}
-
-
-# Return name, href, content. First two may be undefined; third is an array.
-# I don't see how to determine if there are more attributes.
-sub anchor_info ( $ )
-{ my ($he) = check_args(1, @_);
- if ($he->tag ne "a")
- { $he->dump;
- die "passed non-anchor to anchor_info"; }
- my $name = $he->attr('name');
- my $href = $he->attr('href');
- my @content = ();
- { my $ref_content = $he->content;
- if (defined $ref_content)
- { @content = @{$ref_content}; } }
- return ($name, $href, @content);
-}
-
-
-sub texi_quote ( $ )
-{ my ($text) = check_args(1, @_);
- $text =~ s/([\@\{\}])/\@$1/g;
- $text =~ s/ -- / --- /g;
- return $text;
-}
-
-# Eliminate bad punctuation (that confuses Makeinfo or Info) for section titles.
-sub texi_remove_punctuation ( $ )
-{ my ($text) = check_args(1, @_);
-
- $text =~ s/^ +//g;
- $text =~ s/[ :]+$//g;
- $text =~ s/^[1-9][0-9.]* +//g;
- $text =~ s/,//g;
- # Both embedded colons and " -- " confuse makeinfo. (Perhaps " -- "
- # gets converted into " - ", just as "---" would be converted into " -- ",
- # so the names end up differing.)
- # $text =~ s/:/ -- /g;
- $text =~ s/://g;
- return $text;
-}
-
-
-## Do not use this inside `traverse': it throws off the traversal. Use
-## html_replace_by_ignore or html_replace_by_meta instead.
-# Returns 1 if success, 0 if failure.
-sub html_remove ( $;$ )
-{ my ($he, $parent) = check_args_range(1, 2, @_);
- if (!defined $parent)
- { $parent = $he->parent; }
- my $ref_pcontent = $parent->content;
- my @pcontent = @{$ref_pcontent};
- for (my $i=0; $i<scalar(@pcontent); $i++)
- { if ($pcontent[$i] eq $he)
- { splice @{$ref_pcontent}, $i, 1;
- $he->parent(undef);
- return 1; } }
- die "Didn't find $he in $parent";
-}
-
-
-sub html_replace ( $$;$ )
-{ my ($orig, $new, $parent) = check_args_range(2, 3, @_);
- if (!defined $parent)
- { $parent = $orig->parent; }
- my $ref_pcontent = $parent->content;
- my @pcontent = @{$ref_pcontent};
- for (my $i=0; $i<scalar(@pcontent); $i++)
- { if ($pcontent[$i] eq $orig)
- { $ {$ref_pcontent}[$i] = $new;
- $new->parent($parent);
- $orig->parent(undef);
- return 1; } }
- die "Didn't find $orig in $parent";
-}
-
-sub html_replace_by_meta ( $;$ )
-{ my ($orig, $parent) = check_args_range(1, 2, @_);
- my $meta = new HTML::Element "meta";
- if (!defined $parent)
- { $parent = $orig->parent; }
- return html_replace($orig, $meta, $parent);
-}
-
-sub html_replace_by_ignore ( $;$ )
-{ my ($orig, $parent) = check_args_range(1, 2, @_);
- my $ignore = new HTML::Element "ignore";
- if (!defined $parent)
- { $parent = $orig->parent; }
- return html_replace($orig, $ignore, $parent);
-}
-
-
-
-###
-### Collect text elements
-###
-
-my @collected_texts;
-my $collect_texts_stoppoint;
-my $done_collecting;
-
-sub collect_texts ( $;$ )
-{ my ($root, $stop) = check_args_range(1, 2, @_);
- # print STDERR "collect_texts: $root $stop\n";
- $collect_texts_stoppoint = $stop;
- $done_collecting = 0;
- @collected_texts = ();
- $root->traverse(\&collect_if_text); # process texts
- # print STDERR "collect_texts => ", join(";;;", @collected_texts), "\n";
- return @collected_texts;
-}
-
-sub collect_if_text ( $$$ )
-{ my $he = (check_args(3, @_))[0]; # ignore depth and startflag arguments
- if ($done_collecting)
- { return 0; }
- if (!defined $he)
- { return 0; }
- if (!ref $he)
- { push @collected_texts, $he;
- return 0; }
- if ((defined $collect_texts_stoppoint) && ($he eq $collect_texts_stoppoint))
- { $done_collecting = 1;
- return 0; }
- return 1;
-}
-
-
-###########################################################################
-### Clean up parse tree
-###
-
-sub cleanup_parse_tree ( $ )
-{ my ($he) = check_args(1, @_);
- $he->traverse(\&delete_if_navigation, 'ignore text');
- $he->traverse(\&delete_extra_spaces, 'ignore text');
- $he->traverse(\&merge_dl, 'ignore text');
- $he->traverse(\&reorder_dt_and_dl, 'ignore text');
- return $he;
-}
-
-
-## Simpler version that deletes contents but not the element itself.
-# sub delete_if_navigation ( $$$ )
-# { my $he = (check_args(3, @_))[0]; # ignore startflag and depth
-# if (($he->tag() eq "div") && ($he->attr('class') eq 'navigation'))
-# { $he->delete();
-# return 0; }
-# else
-# { return 1; }
-# }
-
-sub delete_if_navigation ( $$$ )
-{ my ($he, $startflag) = (check_args(3, @_))[0,1]; # ignore depth argument
- if (!$startflag)
- { return; }
-
- if (($he->tag() eq "div") && (defined $he->attr('class')) && ($he->attr('class') eq 'navigation'))
- { my $ref_pcontent = $he->parent()->content();
- # Don't try to modify @pcontent, which appears to be a COPY.
- # my @pcontent = @{$ref_pcontent};
- for (my $i = 0; $i<scalar(@{$ref_pcontent}); $i++)
- { if (${$ref_pcontent}[$i] eq $he)
- { splice(@{$ref_pcontent}, $i, 1);
- last; } }
- $he->delete();
- return 0; }
- else
- { return 1; }
-}
-
-sub delete_extra_spaces ( $$$ )
-{ my ($he, $startflag) = (check_args(3, @_))[0,1]; # ignore depth argument
- if (!$startflag)
- { return; }
-
- my $tag = $he->tag;
- if ($tag =~ /^(head|html|table|tr|ul)$/)
- { delete_child_spaces($he); }
- delete_trailing_spaces($he);
- return 1;
-}
-
-
-sub delete_child_spaces ( $ )
-{ my ($he) = check_args(1, @_);
- my $ref_content = $he->content();
- for (my $i = 0; $i<scalar(@{$ref_content}); $i++)
- { if ($ {$ref_content}[$i] =~ /^ *$/)
- { splice(@{$ref_content}, $i, 1);
- $i--; } }
-}
-
-sub delete_trailing_spaces ( $ )
-{ my ($he) = check_args(1, @_);
- my $ref_content = $he->content();
- if (! defined $ref_content)
- { return; }
- # Could also check for previous element = /^h[1-6]$/.
- for (my $i = 0; $i<scalar(@{$ref_content})-1; $i++)
- { if ($ {$ref_content}[$i] =~ /^ *$/)
- { my $next_elt = $ {$ref_content}[$i+1];
- if ((ref $next_elt) && ($next_elt->tag =~ /^(br|dd|dl|dt|hr|p|ul)$/))
- { splice(@{$ref_content}, $i, 1);
- $i--; } } }
- if ($he->tag =~ /^(dd|dt|^h[1-6]|li|p)$/)
- { my $last_elt = $ {$ref_content}[$#{$ref_content}];
- if ((defined $last_elt) && ($last_elt =~ /^ *$/))
- { pop @{$ref_content}; } }
-}
-
-
-# LaTeX2HTML sometimes creates
-# <DT>text
-# <DL COMPACT><DD>text
-# which should actually be:
-# <DL COMPACT>
-# <DT>text
-# <DD>text
-# Since a <DL> gets added, this ends up looking like
-# <P>
-# <DL>
-# <DT>
-# text1...
-# <DL COMPACT>
-# <DD>
-# text2...
-# dt_or_dd1...
-# dt_or_dd2...
-# which should become
-# <P>
-# <DL COMPACT>
-# <DT>
-# text1...
-# <DD>
-# text2...
-# dt_or_dd1...
-# dt_or_dd2...
-
-sub reorder_dt_and_dl ( $$$ )
-{ my ($he, $startflag) = (check_args(3, @_))[0,1]; # ignore depth argument
- if (!$startflag)
- { return; }
-
- if ($he->tag() eq "p")
- { my $ref_pcontent = $he->content();
- if (defined $ref_pcontent)
- { my @pcontent = @{$ref_pcontent};
- # print "reorder_dt_and_dl found a <p>\n"; $he->dump();
- if ((scalar(@pcontent) >= 1)
- && (ref $pcontent[0]) && ($pcontent[0]->tag() eq "dl")
- && $pcontent[0]->implicit())
- { my $ref_dlcontent = $pcontent[0]->content();
- # print "reorder_dt_and_dl found a <p> and implicit <dl>\n";
- if (defined $ref_dlcontent)
- { my @dlcontent = @{$ref_dlcontent};
- if ((scalar(@dlcontent) >= 1)
- && (ref $dlcontent[0]) && ($dlcontent[0]->tag() eq "dt"))
- { my $ref_dtcontent = $dlcontent[0]->content();
- # print "reorder_dt_and_dl found a <p>, implicit <dl>, and <dt>\n";
- if (defined $ref_dtcontent)
- { my @dtcontent = @{$ref_dtcontent};
- if ((scalar(@dtcontent) > 0)
- && (ref $dtcontent[$#dtcontent])
- && ($dtcontent[$#dtcontent]->tag() eq "dl"))
- { my $ref_dl2content = $dtcontent[$#dtcontent]->content();
- # print "reorder_dt_and_dl found a <p>, implicit <dl>, <dt>, and <dl>\n";
- if (defined $ref_dl2content)
- { my @dl2content = @{$ref_dl2content};
- if ((scalar(@dl2content) > 0)
- && (ref ($dl2content[0]))
- && ($dl2content[0]->tag() eq "dd"))
- {
- # print "reorder_dt_and_dl found a <p>, implicit <dl>, <dt>, <dl>, and <dd>\n";
- # print STDERR "CHANGING\n"; $he->dump();
- html_replace_by_ignore($dtcontent[$#dtcontent]);
- splice(@{$ref_dlcontent}, 1, 0, @dl2content);
- # print STDERR "CHANGED TO:\n"; $he->dump();
- return 0; # don't traverse children
- } } } } } } } } }
- return 1;
-}
-
-
-# If we find a paragraph that looks like
-# <P>
-# <HR>
-# <UL>
-# then accumulate its links into a contents_list and delete the paragraph.
-sub process_if_child_links ( $$$ )
-{ my ($he, $startflag) = (check_args(3, @_))[0,1]; # ignore depth argument
- if (!$startflag)
- { return; }
-
- if ($he->tag() eq "p")
- { my $ref_content = $he->content();
- if (defined $ref_content)
- { my @content = @{$ref_content};
- if ((scalar(@content) == 2)
- && (ref $content[0]) && $content[0]->tag() eq "hr"
- && (ref $content[1]) && $content[1]->tag() eq "ul")
- { process_child_links($he);
- $he->delete();
- return 0; } } }
- return 1;
-}
-
-
-# If we find
-# <H4>
-# "Footnotes"
-# <DL>
-# <DT>
-# <A NAME="foot560">
-# "...borrow"
-# <A HREF="refcountsInPython.html#tex2html2" NAME="foot560">
-# "1.2"
-# <DD>
-# "The metaphor of ``borrowing'' a reference is not completely correct: the owner still has a copy of the reference. "
-# ...
-# then record the footnote information and delete the section and list.
-
-my $process_if_footnotes_expect_dl_next = 0;
-
-sub process_if_footnotes ( $$$ )
-{ my ($he, $startflag) = (check_args(3, @_))[0,1]; # ignore depth argument
- if (!$startflag)
- { return; }
-
- if (($he->tag() eq "h4")
- && has_single_content_string($he)
- && ($ {$he->content}[0] eq "Footnotes"))
- { html_replace_by_ignore($he);
- $process_if_footnotes_expect_dl_next = 1;
- return 0; }
-
- if ($process_if_footnotes_expect_dl_next && ($he->tag() eq "dl"))
- { my $ref_content = $he->content();
- if (defined $ref_content)
- { $process_if_footnotes_expect_dl_next = 0;
- my @content = @{$ref_content};
- for (my $i=0; $i<$#content; $i+=2)
- { my $he_dt = $content[$i];
- my $he_dd = $content[$i+1];
- if (($he_dt->tag ne "dt") || ($he_dd->tag ne "dd"))
- { $he->dump;
- die "expected <DT> and <DD> at positions $i and ", $i+1; }
- my @dt_content = @{$he_dt->content()};
- if ((scalar(@dt_content) != 2)
- || ($dt_content[0]->tag ne "a")
- || ($dt_content[1]->tag ne "a"))
- { $he_dt->dump;
- die "Expected 2 anchors as content of <DT>"; }
- my ($dt1_name, $dt1_href, $dt1_content) = anchor_info($dt_content[0]);
- my ($dt2_name, $dt2_href, $dt2_content) = anchor_info($dt_content[0]);
- # unused: $dt1_href, $dt1_content, $dt2_href, $dt2_content
- if ($dt1_name ne $dt2_name)
- { $he_dt->dump;
- die "Expected identical names for anchors"; }
- html_replace_by_ignore($he_dd);
- $he_dd->tag("div"); # has no effect
- $footnotes{$dt1_name} = $he_dd; }
- html_replace_by_ignore($he);
- return 0; } }
-
- if ($process_if_footnotes_expect_dl_next)
- { $he->dump;
- die "Expected <DL> for footnotes next"; }
-
- return 1;
-}
-
-
-
-## Merge two adjacent paragraphs containing <DL> items, such as:
-# <P>
-# <DL>
-# <DT>
-# ...
-# <DD>
-# ...
-# <P>
-# <DL>
-# <DT>
-# ...
-# <DD>
-# ...
-
-sub merge_dl ( $$$ )
-{ my ($he, $startflag) = (check_args(3, @_))[0,1]; # ignore depth argument
- if (!$startflag)
- { return; }
-
- my $ref_content = $he->content;
- if (!defined $ref_content)
- { return; }
- my $i = 0;
- while ($i < scalar(@{$ref_content})-1)
- { my $p1 = $ {$ref_content}[$i];
- if ((ref $p1) && ($p1->tag eq "p")
- && has_single_content_with_tag($p1, "dl"))
- { my $dl1 = $ {$p1->content}[0];
- # In this loop, rhs, not lhs, of < comparison changes,
- # because we are removing elements from the content of $he.
- while ($i < scalar(@{$ref_content})-1)
- { my $p2 = $ {$ref_content}[$i+1];
- if (!((ref $p2) && ($p2->tag eq "p")
- && has_single_content_with_tag($p2, "dl")))
- { last; }
- # Merge these two elements.
- splice(@{$ref_content}, $i+1, 1); # remove $p2
- my $dl2 = $ {$p2->content}[0];
- $dl1->push_content(@{$dl2->content}); # put $dl2's content in $dl1
- }
- # extra increment because next element isn't a candidate for $p1
- $i++; }
- $i++; }
- return 1;
-}
-
-
-
-###########################################################################
-### Testing
-###
-
-sub test ( $$ )
-{ my ($action, $file) = check_args(2, @_);
-
- # General testing
- if (($action eq "view") || ($action eq ""))
- { # # $file = "/homes/gws/mernst/www/links.html";
- # # $file = "/homes/gws/mernst/www/index.html";
- # # $file = "/homes/fish/mernst/java/gud/doc/manual.html";
- # # $file = "/projects/cecil/cecil/doc/manuals/stdlib-man/stdlib/stdlib.html";
- # # $file = "/homes/fish/mernst/tmp/python-doc/html/index.html";
- # $file = "/homes/fish/mernst/tmp/python-doc/html/api/complexObjects.html";
- my $tree = file_to_tree($file);
-
- ## Testing
- # print STDERR $tree->as_HTML;
- $tree->dump();
-
- # print STDERR $tree->tag(), "\n";
- # print STDERR @{$tree->content()}, "\n";
- #
- # for (@{ $tree->extract_links(qw(a img)) }) {
- # my ($link, $linkelem) = @$_;
- # print STDERR "$link ", $linkelem->as_HTML;
- # }
- #
- # print STDERR @{$tree->extract_links()}, "\n";
-
- # my @top_level_elts = @{$tree->content()};
-
- # if scalar(@{$tree->content()})
- return;
- }
-
- elsif ($action eq "raw")
- { my $tree = new HTML::TreeBuilder;
- $tree->ignore_unknown(1);
- # $tree->warn(1);
- $tree->parse_file($file);
-
- $tree->dump();
-
- # cleanup_parse_tree($tree);
- # $tree->dump();
- return;
- }
-
- # Test dealing with a section.
- elsif ($action eq "section")
- { # my $file;
- # $file = "/homes/fish/mernst/tmp/python-doc/html/api/intro.html";
- # $file = "/homes/fish/mernst/tmp/python-doc/html/api/includes.html";
- # $file = "/homes/fish/mernst/tmp/python-doc/html/api/complexObjects.html";
- process_section_file($file, 0, "Title");
- }
-
- # Test dealing with many sections
- elsif (0)
- { my @files = ("/homes/fish/mernst/tmp/python-doc/html/api/about.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/abstract.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/api.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/cObjects.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/complexObjects.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/concrete.html",
- # "/homes/fish/mernst/tmp/python-doc/html/api/contents.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/countingRefs.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/debugging.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/dictObjects.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/embedding.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/exceptionHandling.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/exceptions.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/fileObjects.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/floatObjects.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/front.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/fundamental.html",
- # "/homes/fish/mernst/tmp/python-doc/html/api/genindex.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/importing.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/includes.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/index.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/initialization.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/intObjects.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/intro.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/listObjects.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/longObjects.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/mapObjects.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/mapping.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/newTypes.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/node24.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/noneObject.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/number.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/numericObjects.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/object.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/objects.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/os.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/otherObjects.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/processControl.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/refcountDetails.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/refcounts.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/sequence.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/sequenceObjects.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/standardExceptions.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/stringObjects.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/threads.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/tupleObjects.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/typeObjects.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/types.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/utilities.html",
- "/homes/fish/mernst/tmp/python-doc/html/api/veryhigh.html");
- for my $file (@files)
- { print STDERR "\n", "=" x 75, "\n", "$file:\n";
- process_section_file($file, 0, "Title");
- }
- }
-
- # Test dealing with index.
- elsif ($action eq "index")
- { # my $file;
- # $file = "/homes/fish/mernst/tmp/python-doc/html/api/genindex.html";
-
- process_index_file($file, "\@cindex");
- print_index_info();
- }
-
- else
- { die "Unrecognized action `$action'"; }
-}
-
-
-###########################################################################
-### Main loop
-###
-
-sub process_contents_file ( $ )
-{ my ($file) = check_args(1, @_);
-
- # could also use File::Basename
- my $info_file = $file;
- $info_file =~ s/(\/?index)?\.html$//;
- if ($info_file eq "")
- { chomp($info_file = `pwd`); }
- $info_file =~ s/^.*\///; # not the most efficient way to remove dirs
-
- $html_directory = $file;
- $html_directory =~ s/(\/|^)[^\/]+$/$1/;
-
- my $texi_file = "$info_file.texi";
- open(TEXI, ">$texi_file");
-
- print TEXI "\\input texinfo \@c -*-texinfo-*-\n";
- print TEXI "\@c %**start of header\n";
- print TEXI "\@setfilename $info_file\n";
-
- # 2. Summary Description and Copyright
- # The "Summary Description and Copyright" segment describes the
- # document and contains the copyright notice and copying permissions
- # for the Info file. The segment must be enclosed between `@ifinfo'
- # and `@end ifinfo' commands so that the formatters place it only in
- # the Info file.
- #
- # The summary description and copyright segment does not appear in the
- # printed document.
- #
- # @ifinfo
- # This is a short example of a complete Texinfo file.
- #
- # Copyright @copyright{} 1990 Free Software Foundation, Inc.
- # @end ifinfo
-
-
- # 3. Title and Copyright
- # The "Title and Copyright" segment contains the title and copyright
- # pages and copying permissions for the printed manual. The segment
- # must be enclosed between `@titlepage' and `@end titlepage'
- # commands. The title and copyright page appear only in the printed
- # manual.
- #
- # The titlepage segment does not appear in the Info file.
- #
- # @titlepage
- # @sp 10
- # @comment The title is printed in a large font.
- # @center @titlefont{Sample Title}
- #
- # @c The following two commands start the copyright page.
- # @page
- # @vskip 0pt plus 1filll
- # Copyright @copyright{} 1990 Free Software Foundation, Inc.
- # @end titlepage
-
-
- # 4. `Top' Node and Master Menu
- # The "Master Menu" contains a complete menu of all the nodes in the
- # whole Info file. It appears only in the Info file, in the `Top'
- # node.
- #
- # The `Top' node contains the master menu for the Info file. Since a
- # printed manual uses a table of contents rather than a menu, the master
- # menu appears only in the Info file.
- #
- # @node Top, First Chapter, , (dir)
- # @comment node-name, next, previous, up
- #
- # @menu
- # * First Chapter:: The first chapter is the
- # only chapter in this sample.
- # * Concept Index:: This index has two entries.
- # @end menu
-
-
-
- $current_ref_tdf = [ "Top", 0, $ARGV[0] ];
- process_section_file($file, 0, "Top");
- while (scalar(@contents_list))
- { $current_ref_tdf = shift @contents_list;
- process_section_file($ {$current_ref_tdf}[2], $ {$current_ref_tdf}[1], $ {$current_ref_tdf}[0]);
- }
-
- print TEXI "\n";
- for my $indextitle (@index_titles)
- { print TEXI "\@node $indextitle\n";
- print TEXI "\@unnumbered $indextitle\n";
- print TEXI "\@printindex $ {$index_info{$indextitle}}[1]\n";
- print TEXI "\n"; }
-
- print TEXI "\@contents\n";
- print TEXI "\@bye\n";
- close(TEXI);
-}
-
-# This needs to be last so global variable initializations are reached.
-
-if (scalar(@ARGV) == 0)
-{ die "No arguments supplied to html2texi.pl"; }
-
-if ($ARGV[0] eq "-test")
-{ my @test_args = @ARGV[1..$#ARGV];
- if (scalar(@test_args) == 0)
- { test("", "index.html"); }
- elsif (scalar(@test_args) == 1)
- { test("", $test_args[0]); }
- elsif (scalar(@test_args) == 2)
- { test($test_args[0], $test_args[1]); }
- else
- { die "Too many test arguments passed to html2texi: ", join(" ", @ARGV); }
- exit();
-}
-
-if (scalar(@ARGV) != 1)
-{ die "Pass one argument, the main/contents page"; }
-
-process_contents_file($ARGV[0]);
-
-# end of html2texi.pl
diff --git a/Doc/tools/indfix.py b/Doc/tools/indfix.py
deleted file mode 100755
index 23f9e17..0000000
--- a/Doc/tools/indfix.py
+++ /dev/null
@@ -1,100 +0,0 @@
-#! /usr/bin/env python
-
-"""Combine similar index entries into an entry and subentries.
-
-For example:
-
- \item {foobar} (in module flotz), 23
- \item {foobar} (in module whackit), 4323
-
-becomes
-
- \item {foobar}
- \subitem in module flotz, 23
- \subitem in module whackit, 4323
-
-Note that an item which matches the format of a collapsable item but which
-isn't part of a group of similar items is not modified.
-"""
-__version__ = '$Revision$'
-
-import re
-import io
-import sys
-
-
-def cmp_entries(e1, e2):
- return cmp(e1[1].lower(), e2[1].lower()) or cmp(e1, e2)
-
-
-def dump_entries(write, entries):
- if len(entries) == 1:
- write(" \\item %s (%s)%s\n" % entries[0])
- return
- write(" \item %s\n" % entries[0][0])
- # now sort these in a case insensitive manner:
- if len(entries) > 0:
- entries.sort(cmp_entries)
- for xxx, subitem, pages in entries:
- write(" \subitem %s%s\n" % (subitem, pages))
-
-
-breakable_re = re.compile(
- r" \\item (.*) [(](.*)[)]((?:(?:, \d+)|(?:, \\[a-z]*\{\d+\}))+)")
-
-
-def process(ifn, ofn=None):
- if ifn == "-":
- ifp = sys.stdin
- else:
- ifp = open(ifn)
- if ofn is None:
- ofn = ifn
- ofp = io.StringIO()
- entries = []
- match = breakable_re.match
- write = ofp.write
- while 1:
- line = ifp.readline()
- if not line:
- break
- m = match(line)
- if m:
- entry = m.group(1, 2, 3)
- if entries and entries[-1][0] != entry[0]:
- dump_entries(write, entries)
- entries = []
- entries.append(entry)
- elif entries:
- dump_entries(write, entries)
- entries = []
- write(line)
- else:
- write(line)
- del write
- del match
- ifp.close()
- data = ofp.getvalue()
- ofp.close()
- if ofn == "-":
- ofp = sys.stdout
- else:
- ofp = open(ofn, "w")
- ofp.write(data)
- ofp.close()
-
-
-def main():
- import getopt
- outfile = None
- opts, args = getopt.getopt(sys.argv[1:], "o:")
- for opt, val in opts:
- if opt in ("-o", "--output"):
- outfile = val
- filename = args[0]
- outfile = outfile or filename
- process(filename, outfile)
-
-
-if __name__ == "__main__":
- main()
diff --git a/Doc/tools/keywords.py b/Doc/tools/keywords.py
deleted file mode 100644
index f9e4b03..0000000
--- a/Doc/tools/keywords.py
+++ /dev/null
@@ -1,25 +0,0 @@
-#! /usr/bin/env python
-
-# This Python program sorts and reformats the table of keywords in ref2.tex
-
-def raw_input(prompt):
- import sys
- sys.stdout.write(prompt)
- sys.stdout.flush()
- return sys.stdin.readline()
-
-l = []
-try:
- while 1:
- l = l + raw_input().split()
-except EOFError:
- pass
-l.sort()
-for x in l[:]:
- while l.count(x) > 1: l.remove(x)
-ncols = 5
-nrows = (len(l)+ncols-1)/ncols
-for i in range(nrows):
- for j in range(i, len(l), nrows):
- print(l[j].ljust(10), end=' ')
- print()
diff --git a/Doc/tools/listmodules b/Doc/tools/listmodules
deleted file mode 100755
index a60496b..0000000
--- a/Doc/tools/listmodules
+++ /dev/null
@@ -1,182 +0,0 @@
-#! /usr/bin/env python
-# -*- Python -*-
-#
-# This script can be used to identify undocumented modules in the Python
-# standard library. Use it like this:
-#
-# .../Doc/tools/listmodules --ignore-from .../Doc/paper-<paper>/modlib.idx
-
-"""%(program)s - list modules in the Python standard library
-
--a, --annotate Annotate the module names with the subdirectory they
- live in
--c, --categorize Group the modules by subdirectory
--i <file>,
-
---ignore-from <file> Ignore the modules listed in <file>. <file> may
- contain a list of module names or a module index file
- as produced when formatting the Python documentation
- (.idx or .html flavor).
-
-If neither -a nor -c are given, the modules are listed in alphabetical
-order.
-
-Note that -a and -c are mutually exclusive.
-
-Limitation: Modules loadable as shared objects may not be listed,
-though this script attempts to locate such modules.
-
-"""
-
-__version__ = '$Revision$'
-
-import getopt
-import glob
-import os
-import re
-import sys
-
-
-REMOVE_DIRS = ["encodings", "distutils",
- "lib-old", ""test"]
-
-
-def main():
- args = sys.argv[1:]
- annotate = 0
- builtin = 0
- categorize = 0
- ignore_dict = {}
- ignore = ignore_dict.has_key
- try:
- opts, args = getopt.getopt(
- args, "abchi:",
- ["annotate", "built-in", "categorize", "help", "ignore-from="])
- except getopt.error as msg:
- sys.stdout = sys.stderr
- print msg
- print
- usage()
- sys.exit(2)
- for opt, arg in opts:
- if opt in ("-a", "--annotate"):
- annotate = 1
- elif opt in ("-b", "--built-in"):
- builtin = 1
- elif opt in ("-c", "--categorize"):
- categorize = 1
- elif opt in ("-h", "--help"):
- usage()
- sys.exit()
- elif opt in ("-i", "--ignore-from"):
- data = open(arg).read()
- if data[:1] == "\\":
- ignore_from_idx(data, ignore_dict)
- else:
- ignore_from_modulelist(data, ignore_dict)
- if args or (annotate and categorize):
- usage()
- sys.exit(2)
- #
- # Populate the database:
- #
- srcdir = os.path.normpath(os.path.join(
- os.path.dirname(sys.argv[0]), os.pardir, os.pardir))
- os.chdir(srcdir)
- modules_by_name = {}
- modules_by_dir = {}
- if builtin:
- l = []
- modules_by_dir["<builtin>"] = l
- for name in sys.builtin_module_names:
- if not ignore(name):
- modules_by_name[name] = "<built-in>"
- l.append(name)
- rx = re.compile("Lib/plat-[a-zA-Z0-9]*/")
- fp = os.popen("find Lib -name \*.py -print", "r")
- while 1:
- line = fp.readline()
- if not line:
- break
- m = rx.match(line)
- if m:
- line = "Lib/plat-*/" + line[m.end():]
- line = line[4:-4] # strip off 'Lib/' and '.py\n'
- dir, name = os.path.split(line)
- dir = dir or "<standard>"
- if ignore(name):
- continue
- if dir not in REMOVE_DIRS:
- modules_by_name[name] = dir
- l = modules_by_dir.get(dir, [])
- modules_by_dir[dir] = l
- if name not in l:
- l.append(name)
- # load up extension modules:
- pwd = os.getcwd()
- try:
- os.chdir("Modules")
- dir = "<extension>"
- for line in glob.glob("*module.c"):
- name = line[:-8]
- if ignore(name) or modules_by_name.has_key(name) or name == "xx":
- continue
- modules_by_name[name] = dir
- l = modules_by_dir.get(dir, [])
- modules_by_dir[dir] = l
- if name not in l:
- l.append(name)
- finally:
- os.chdir(pwd)
- #
- # Dump the results:
- #
- if annotate:
- modules = modules_by_name.items()
- modules.sort()
- width = max(map(len, modules_by_name.keys()))
- format = "%%-%ds %%s" % width
- for name, dir in modules:
- if dir and dir[0] != "<":
- print format % (name, dir)
- else:
- print name
- elif categorize:
- modules = modules_by_dir.items()
- modules.sort()
- width = max(map(len, modules_by_dir.keys()))
- format = "%%-%ds %%s" % width
- for dir, names in modules:
- names.sort()
- print format % (dir, names[0])
- for name in names[1:]:
- print format % ('', name)
- print
- else:
- modules = modules_by_name.keys()
- modules.sort()
- print "\n".join(modules)
-
-
-def ignore_from_modulelist(data, ignore_dict):
- for name in data.split():
- ignore_dict[name] = name
-
-def ignore_from_idx(data, ignore_dict):
- data = data.replace(r"\hackscore {}", "_")
- rx = re.compile(r"\\indexentry\s*{([^@]*)@")
- for line in data.split("\n"):
- m = rx.match(line)
- if m:
- name = m.group(1)
- ignore_dict[name] = name
-
-
-def usage():
- vars = {}
- vars["program"] = os.path.basename(sys.argv[0])
- print __doc__ % vars
-
-
-if __name__ == "__main__":
- main()
diff --git a/Doc/tools/listmodules.py b/Doc/tools/listmodules.py
deleted file mode 100644
index 8acdf43..0000000
--- a/Doc/tools/listmodules.py
+++ /dev/null
@@ -1,125 +0,0 @@
-# $Id$
-#
-# Locate all standard modules available in this build.
-#
-# This script is designed to run on Python 1.5.2 and newer.
-#
-# Written by Fredrik Lundh, January 2005
-#
-
-import imp, sys, os, re, time
-
-identifier = "python-%s-%s" % (sys.version[:3], sys.platform)
-timestamp = time.strftime("%Y%m%dT%H%M%SZ", time.gmtime(time.time()))
-
-# known test packages
-TEST_PACKAGES = "test.", "bsddb.test.", "distutils.tests."
-
-try:
- import platform
- platform = platform.platform()
-except:
- platform = None # unknown
-
-suffixes = imp.get_suffixes()
-
-def get_suffix(file):
- for suffix in suffixes:
- if file[-len(suffix[0]):] == suffix[0]:
- return suffix
- return None
-
-def main():
-
- path = getpath()
-
- modules = {}
- for m in sys.builtin_module_names:
- modules[m] = None
-
- for p in path:
- modules.update(getmodules(p))
-
- keys = sorted(modules.keys())
-
- # filter out known test packages
- def cb(m):
- for d in TEST_PACKAGES:
- if m[:len(d)] == d:
- return 0
- return 1
- keys = filter(cb, keys)
-
- try:
- outfile = sys.argv[1]
- if outfile == "-":
- outfile = None
- elif outfile == "-f":
- outfile = "modules-" + identifier + ".txt"
- except IndexError:
- outfile = None
-
- if not outfile:
- out = sys.stdout
- else:
- out = open(outfile, "w")
-
- out.write("# module list (generated by listmodules.py)\n")
- out.write("#\n")
- out.write("# timestamp=%s\n" % repr(timestamp))
- out.write("# sys.version=%s\n" % repr(sys.version))
- out.write("# sys.platform=%s\n" % repr(sys.platform))
- if platform:
- out.write("# platform=%s\n" % repr(platform))
- out.write("#\n")
-
- for k in keys:
- out.write(k + "\n")
-
- if out is not sys.stdout:
- out.close()
- print(out.name, "ok (%d modules)" % len(modules))
-
-def getmodules(p):
- # get modules in a given directory
- modules = {}
- for f in os.listdir(p):
- f = os.path.join(p, f)
- if os.path.isfile(f):
- m, e = os.path.splitext(f)
- suffix = get_suffix(f)
- if not suffix:
- continue
- m = os.path.basename(m)
- if re.compile("(?i)[a-z_]\w*$").match(m):
- if suffix[2] == imp.C_EXTENSION:
- # check that this extension can be imported
- try:
- __import__(m)
- except ImportError:
- continue
- modules[m] = f
- elif os.path.isdir(f):
- m = os.path.basename(f)
- if os.path.isfile(os.path.join(f, "__init__.py")):
- for mm, f in getmodules(f).items():
- modules[m + "." + mm] = f
- return modules
-
-def getpath():
- path = map(os.path.normcase, map(os.path.abspath, sys.path[:]))
- # get rid of site packages
- for p in path:
- if p[-13:] == "site-packages":
- def cb(p, site_package_path=os.path.abspath(p)):
- return p[:len(site_package_path)] != site_package_path
- path = filter(cb, path)
- break
- # get rid of non-existent directories and the current directory
- def cb(p, cwd=os.path.normcase(os.getcwd())):
- return os.path.isdir(p) and p != cwd
- path = filter(cb, path)
- return path
-
-if __name__ == "__main__":
- main()
diff --git a/Doc/tools/makesec.sh b/Doc/tools/makesec.sh
deleted file mode 100755
index 6159d6f..0000000
--- a/Doc/tools/makesec.sh
+++ /dev/null
@@ -1,129 +0,0 @@
-#!/bin/sh
-
-# Simple little checker for individual libref manual sections
-#
-# usage: makesec.sh section
-#
-
-# This script builds the minimal file necessary to run a single section
-# through latex, does so, then converts the resulting dvi file to ps or pdf
-# and feeds the result into a viewer. It's by no means foolproof, but seems
-# to work okay for me (knock wood). It sure beats manually commenting out
-# most of the man lib.tex file and running everything manually.
-
-# It attempts to locate an appropriate dvi converter and viewer for the
-# selected output format. It understands the following environment
-# variables:
-#
-# PYSRC - refers to the root of your build tree (dir containing Doc)
-# DVICVT - refers to a dvi converter like dvips or dvipdf
-# VIEWER - refers to an appropriate viewer for the ps/pdf file
-#
-# Of the three, only PYSRC is currently required. The other two can be set
-# to specify unusual tools which perform those tasks.
-
-# Known issues:
-# - It would be nice if the script could determine PYSRC on its own.
-# - Something about \seealso{}s blows the latex stack, so they need
-# to be commented out for now.
-
-if [ x$PYSRC = x ] ; then
- echo "PYSRC must refer to the Python source tree" 1>&2
- exit 1
-fi
-
-if [ ! -d $PYSRC/Doc ] ; then
- echo "Can't find a Doc subdirectory in $PYSRC" 1>&2
- exit 1
-fi
-
-if [ "$#" -ne 1 ] ; then
- echo "Must specify a single libref manual section on cmd line" 1>&2
- exit 1
-fi
-
-# settle on a dvi converter
-if [ x$DVICVT != x ] ; then
- converter=$DVICVT
- ext=`echo $DVICVT | sed -e 's/^dvi//'`
- result=lib.$ext
-elif [ x`which dvipdf` != x ] ; then
- converter=`which dvipdf`
- ext=.pdf
-elif [ x`which dvips` != x ] ; then
- converter=`which dvips`
- ext=.ps
-else
- echo "Can't find a reasonable dvi converter" 1>&2
- echo "Set DVICVT to refer to one" 1>&2
- exit 1
-fi
-
-# how about a viewer?
-if [ x$VIEWER != x ] ; then
- viewer=$VIEWER
-elif [ $ext = ".ps" -a x`which gv` != x ] ; then
- viewer=gv
-elif [ $ext = ".ps" -a x`which gs` != x ] ; then
- viewer=gs
-elif [ $ext = ".pdf" -a x`which acroread` != x ] ; then
- viewer=acroread
-elif [ $ext = ".pdf" -a "`uname`" = "Darwin" -a x`which open` != x ] ; then
- viewer=open
-elif [ $ext = ".pdf" -a x`which acroread` != x ] ; then
- viewer=acroread
-else
- echo "Can't find a reasonable viewer" 1>&2
- echo "Set VIEWER to refer to one" 1>&2
- exit 1
-fi
-
-# make sure necessary links are in place
-for f in howto.cls pypaper.sty ; do
- rm -f $f
- ln -s $PYSRC/Doc/$f
-done
-
-export TEXINPUTS=.:$PYSRC/Doc/texinputs:
-
-# strip extension in case they gave full filename
-inp=`basename $1 .tex`
-
-# create the minimal framework necessary to run section through latex
-tmpf=lib.tex
-cat > $tmpf <<EOF
-\documentclass{manual}
-
-% NOTE: this file controls which chapters/sections of the library
-% manual are actually printed. It is easy to customize your manual
-% by commenting out sections that you are not interested in.
-
-\title{Python Library Reference}
-
-\input{boilerplate}
-
-\makeindex % tell \index to actually write the
- % .idx file
-\makemodindex % ... and the module index as well.
-
-
-\begin{document}
-
-\maketitle
-
-\ifhtml
-\chapter*{Front Matter\label{front}}
-\fi
-
-\input{$inp}
-\end{document}
-EOF
-
-latex $tmpf
-
-$converter lib
-
-$viewer lib.pdf
-
-rm -f $tmpf howto.cls pypaper.sty *.idx *.syn
-rm -f lib.aux lib.log
diff --git a/Doc/tools/mkackshtml b/Doc/tools/mkackshtml
deleted file mode 100755
index ac126e0..0000000
--- a/Doc/tools/mkackshtml
+++ /dev/null
@@ -1,65 +0,0 @@
-#! /usr/bin/env python
-# -*- Python -*-
-
-import support
-import sys
-
-
-def collect(fp):
- names = []
- while 1:
- line = fp.readline()
- if not line:
- break
- line = line.strip()
- if line:
- names.append(line)
- else:
- names = []
- return names
-
-
-def main():
- options = support.Options()
- options.columns = 4
- options.variables["title"] = "Acknowledgements"
- options.parse(sys.argv[1:])
- names = collect(sys.stdin)
- percol = (len(names) + options.columns - 1) // options.columns
- colnums = []
- for i in range(options.columns):
- colnums.append(percol*i)
- options.aesop_type = "information"
- fp = options.get_output_file()
- fp.write(options.get_header().rstrip() + "\n")
- fp.write(THANKS + "\n")
- fp.write('<table width="100%" align="center">\n')
- for i in range(percol):
- fp.write(" <tr>\n")
- for j in colnums:
- try:
- fp.write(" <td>%s</td>\n" % names[i + j])
- except IndexError:
- pass
- fp.write(" </tr>\n")
- fp.write("</table>\n")
- fp.write(options.get_footer().rstrip() + "\n")
- fp.close()
-
-THANKS = '''\
-
-<p>These people have contributed in some way to the Python
-documentation. This list is probably not complete -- if you feel that
-you or anyone else should be on this list, please let us know (send
-email to <a
-href="mailto:docs@python.org">docs@python.org</a>), and
-we will be glad to correct the problem.</p>
-
-<p>It is only with the input and contributions of the Python community
-that Python has such wonderful documentation -- <b>Thank You!</b></p>
-
-'''
-
-
-if __name__ == "__main__":
- main()
diff --git a/Doc/tools/mkhowto b/Doc/tools/mkhowto
deleted file mode 100755
index fa259e0..0000000
--- a/Doc/tools/mkhowto
+++ /dev/null
@@ -1,659 +0,0 @@
-#! /usr/bin/env python
-# -*- Python -*-
-"""usage: %(program)s [options...] file ...
-
-Options specifying formats to build:
- --html HyperText Markup Language (default)
- --pdf Portable Document Format
- --ps PostScript
- --dvi 'DeVice Indepentent' format from TeX
- --text ASCII text (requires lynx)
-
- More than one output format may be specified, or --all.
-
-HTML options:
- --address, -a Specify an address for page footers.
- --dir Specify the directory for HTML output.
- --link Specify the number of levels to include on each page.
- --split, -s Specify a section level for page splitting, default: %(max_split_depth)s.
- --iconserver, -i Specify location of icons (default: ./).
- --image-type Specify the image type to use in HTML output;
- values: gif, png (default).
- --numeric Don't rename the HTML files; just keep node#.html for
- the filenames.
- --style Specify the CSS file to use for the output (filename,
- not a URL).
- --up-link URL to a parent document.
- --up-title Title of a parent document.
- --favicon Icon to display in the browsers location bar.
-
-Other options:
- --a4 Format for A4 paper.
- --letter Format for US letter paper (the default).
- --help, -H Show this text.
- --logging, -l Log stdout and stderr to a file (*.how).
- --debugging, -D Echo commands as they are executed.
- --keep, -k Keep temporary files around.
- --quiet, -q Do not print command output to stdout.
- (stderr is also lost, sorry; see *.how for errors)
-"""
-
-import getopt
-import glob
-import os
-import re
-import shutil
-import sys
-
-
-MYDIR = os.path.abspath(sys.path[0])
-TOPDIR = os.path.dirname(MYDIR)
-
-ISTFILE = os.path.join(TOPDIR, "texinputs", "python.ist")
-NODE2LABEL_SCRIPT = os.path.join(MYDIR, "node2label.pl")
-L2H_INIT_FILE = os.path.join(TOPDIR, "perl", "l2hinit.perl")
-
-BIBTEX_BINARY = "bibtex"
-DVIPS_BINARY = "dvips"
-LATEX_BINARY = "latex"
-LATEX2HTML_BINARY = "latex2html"
-LYNX_BINARY = "lynx"
-MAKEINDEX_BINARY = "makeindex"
-PDFLATEX_BINARY = "pdflatex"
-PERL_BINARY = "perl"
-PYTHON_BINARY = "python"
-
-
-def usage(options, file):
- print(__doc__ % options, file=file)
-
-def error(options, message, err=2):
- print(message, file=sys.stderr)
- print(file=sys.stderr)
- usage(options, sys.stderr)
- sys.exit(2)
-
-
-class Options:
- program = os.path.basename(sys.argv[0])
- #
- address = ''
- builddir = None
- debugging = 0
- discard_temps = 1
- have_temps = 0
- icon_server = "."
- image_type = "png"
- logging = 0
- max_link_depth = 3
- max_split_depth = 6
- paper = "letter"
- quiet = 0
- runs = 0
- numeric = 0
- global_module_index = None
- style_file = os.path.join(TOPDIR, "html", "style.css")
- about_file = os.path.join(TOPDIR, "html", "about.dat")
- up_link = None
- up_title = None
- favicon = None
- #
- # 'dvips_safe' is a weird option. It is used mostly to make
- # LaTeX2HTML not try to be too smart about protecting the user
- # from a bad version of dvips -- some versions would core dump if
- # the path to the source DVI contained a dot, and it's appearantly
- # difficult to determine if the version available has that bug.
- # This option gets set when PostScript output is requested
- # (because we're going to run dvips regardless, and we'll either
- # know it succeeds before LaTeX2HTML is run, or we'll have
- # detected the failure and bailed), or the user asserts that it's
- # safe from the command line.
- #
- # So, why does LaTeX2HTML think it appropriate to protect the user
- # from a dvips that's only potentially going to core dump? Only
- # because they want to avoid doing a lot of work just to have to
- # bail later with no useful intermediates. Unfortunately, they
- # bail *before* they know whether dvips will be needed at all.
- # I've gone around the bush a few times with the LaTeX2HTML
- # developers over whether this is appropriate behavior, and they
- # don't seem interested in changing their position.
- #
- dvips_safe = 0
- #
- DEFAULT_FORMATS = ("html",)
- ALL_FORMATS = ("dvi", "html", "pdf", "ps", "text")
-
- def __init__(self):
- self.formats = []
- self.l2h_init_files = []
-
- def __getitem__(self, key):
- # This is used when formatting the usage message.
- try:
- return getattr(self, key)
- except AttributeError:
- raise KeyError(key)
-
- def parse(self, args):
- opts, args = getopt.getopt(args, "Hi:a:s:lDkqr:",
- ["all", "postscript", "help", "iconserver=",
- "address=", "a4", "letter", "l2h-init=",
- "link=", "split=", "logging", "debugging",
- "keep", "quiet", "runs=", "image-type=",
- "about=", "numeric", "style=", "paper=",
- "up-link=", "up-title=", "dir=",
- "global-module-index=", "dvips-safe",
- "favicon="]
- + list(self.ALL_FORMATS))
- for opt, arg in opts:
- if opt == "--all":
- self.formats = list(self.ALL_FORMATS)
- self.dvips_safe = "ps" in self.formats
- elif opt in ("-H", "--help"):
- usage(self, sys.stdout)
- sys.exit()
- elif opt == "--iconserver":
- self.icon_server = arg
- elif opt in ("-a", "--address"):
- self.address = arg
- elif opt == "--a4":
- self.paper = "a4"
- elif opt == "--letter":
- self.paper = "letter"
- elif opt == "--link":
- self.max_link_depth = int(arg)
- elif opt in ("-s", "--split"):
- self.max_split_depth = int(arg)
- elif opt in ("-l", "--logging"):
- self.logging = self.logging + 1
- elif opt in ("-D", "--debugging"):
- self.debugging = self.debugging + 1
- elif opt in ("-k", "--keep"):
- self.discard_temps = 0
- elif opt in ("-q", "--quiet"):
- self.quiet = 1
- elif opt in ("-r", "--runs"):
- self.runs = int(arg)
- elif opt == "--image-type":
- self.image_type = arg
- elif opt == "--about":
- # always make this absolute:
- self.about_file = os.path.normpath(
- os.path.abspath(arg))
- elif opt == "--numeric":
- self.numeric = 1
- elif opt == "--style":
- self.style_file = os.path.abspath(arg)
- elif opt == "--l2h-init":
- self.l2h_init_files.append(os.path.abspath(arg))
- elif opt == "--favicon":
- self.favicon = arg
- elif opt == "--up-link":
- self.up_link = arg
- elif opt == "--up-title":
- self.up_title = arg
- elif opt == "--global-module-index":
- self.global_module_index = arg
- elif opt == "--dir":
- if os.sep == "\\":
- arg = re.sub("/", "\\\\", arg)
- self.builddir = os.path.expanduser(arg)
- elif opt == "--paper":
- self.paper = arg
- elif opt == "--dvips-safe":
- self.dvips_safe = 1
- #
- # Format specifiers:
- #
- elif opt[2:] in self.ALL_FORMATS:
- self.add_format(opt[2:])
- elif opt == "--postscript":
- # synonym for --ps
- self.add_format("ps")
- self.initialize()
- #
- # return the args to allow the caller access:
- #
- return args
-
- def add_format(self, format):
- """Add a format to the formats list if not present."""
- if not format in self.formats:
- if format == "ps":
- # assume this is safe since we're going to run it anyway
- self.dvips_safe = 1
- self.formats.append(format)
-
- def initialize(self):
- """Complete initialization. This is needed if parse() isn't used."""
- # add the default format if no formats were specified:
- if not self.formats:
- self.formats = self.DEFAULT_FORMATS
- # determine the base set of texinputs directories:
- texinputs = os.environ.get("TEXINPUTS", "").split(os.pathsep)
- if not texinputs:
- texinputs = ['']
- mydirs = [os.path.join(TOPDIR, "paper-" + self.paper),
- os.path.join(TOPDIR, "texinputs"),
- ]
- if '' in texinputs:
- i = texinputs.index('')
- texinputs[i:i] = mydirs
- else:
- texinputs += mydirs
- self.base_texinputs = texinputs
- if self.builddir:
- self.builddir = os.path.abspath(self.builddir)
-
-
-class Job:
- latex_runs = 0
-
- def __init__(self, options, path):
- self.options = options
- self.doctype = get_doctype(path)
- self.filedir, self.doc = split_pathname(path)
- self.builddir = os.path.abspath(options.builddir or self.doc)
- if ("html" in options.formats or "text" in options.formats):
- if not os.path.exists(self.builddir):
- os.mkdir(self.builddir)
- self.log_filename = os.path.join(self.builddir, self.doc + ".how")
- else:
- self.log_filename = os.path.abspath(self.doc + ".how")
- if os.path.exists(self.log_filename):
- os.unlink(self.log_filename)
- l2hconf = self.doc + ".l2h"
- if os.path.exists(l2hconf):
- if os.path.exists(l2hconf + "~"):
- os.unlink(l2hconf + "~")
- os.rename(l2hconf, l2hconf + "~")
- self.l2h_aux_init_file = self.doc + ".l2h"
- self.write_l2h_aux_init_file()
-
- def build(self):
- self.setup_texinputs()
- formats = self.options.formats
- if "dvi" in formats or "ps" in formats:
- self.build_dvi()
- if "pdf" in formats:
- self.build_pdf()
- if "ps" in formats:
- self.build_ps()
- if "html" in formats:
- self.require_temps()
- self.build_html(self.builddir)
- if self.options.icon_server == ".":
- pattern = os.path.join(TOPDIR, "html", "icons",
- "*." + self.options.image_type)
- imgs = glob.glob(pattern)
- if not imgs:
- self.warning(
- "Could not locate support images of type %s."
- % repr(self.options.image_type))
- for fn in imgs:
- new_fn = os.path.join(self.builddir, os.path.basename(fn))
- shutil.copyfile(fn, new_fn)
- if "text" in formats:
- self.require_temps()
- tempdir = self.doc
- need_html = "html" not in formats
- if self.options.max_split_depth != 1:
- fp = open(self.l2h_aux_init_file, "a")
- fp.write("# re-hack this file for --text:\n")
- l2hoption(fp, "MAX_SPLIT_DEPTH", "1")
- fp.write("1;\n")
- fp.close()
- tempdir = self.doc + "-temp-html"
- need_html = 1
- if need_html:
- self.build_html(tempdir, max_split_depth=1)
- self.build_text(tempdir)
- if self.options.discard_temps:
- self.cleanup()
-
- def setup_texinputs(self):
- texinputs = [self.filedir] + self.options.base_texinputs
- os.environ["TEXINPUTS"] = os.pathsep.join(texinputs)
- self.message("TEXINPUTS=" + os.environ["TEXINPUTS"])
-
- def build_aux(self, binary=None):
- if binary is None:
- binary = LATEX_BINARY
- new_index( "%s.ind" % self.doc, "genindex")
- new_index("mod%s.ind" % self.doc, "modindex")
- self.run("%s %s" % (binary, self.doc))
- self.use_bibtex = check_for_bibtex(self.doc + ".aux")
- self.latex_runs = 1
-
- def build_dvi(self):
- self.use_latex(LATEX_BINARY)
-
- def build_pdf(self):
- self.use_latex(PDFLATEX_BINARY)
-
- def use_latex(self, binary):
- self.require_temps(binary=binary)
- if self.latex_runs < 2:
- if os.path.isfile("mod%s.idx" % self.doc):
- self.run("%s mod%s.idx" % (MAKEINDEX_BINARY, self.doc))
- use_indfix = 0
- if os.path.isfile(self.doc + ".idx"):
- use_indfix = 1
- # call to Doc/tools/fix_hack omitted; doesn't appear necessary
- self.run("%s %s.idx" % (MAKEINDEX_BINARY, self.doc))
- import indfix
- indfix.process(self.doc + ".ind")
- if self.use_bibtex:
- self.run("%s %s" % (BIBTEX_BINARY, self.doc))
- self.process_synopsis_files()
- self.run("%s %s" % (binary, self.doc))
- self.latex_runs = self.latex_runs + 1
- if os.path.isfile("mod%s.idx" % self.doc):
- self.run("%s -s %s mod%s.idx"
- % (MAKEINDEX_BINARY, ISTFILE, self.doc))
- if use_indfix:
- self.run("%s -s %s %s.idx"
- % (MAKEINDEX_BINARY, ISTFILE, self.doc))
- indfix.process(self.doc + ".ind")
- self.process_synopsis_files()
- #
- # and now finish it off:
- #
- if os.path.isfile(self.doc + ".toc") and binary == PDFLATEX_BINARY:
- import toc2bkm
- if self.doctype == "manual":
- bigpart = "chapter"
- else:
- bigpart = "section"
- toc2bkm.process(self.doc + ".toc", self.doc + ".bkm", bigpart)
- if self.use_bibtex:
- self.run("%s %s" % (BIBTEX_BINARY, self.doc))
- self.run("%s %s" % (binary, self.doc))
- self.latex_runs = self.latex_runs + 1
-
- def process_synopsis_files(self):
- synopsis_files = glob.glob(self.doc + "*.syn")
- for path in synopsis_files:
- uniqify_module_table(path)
-
- def build_ps(self):
- self.run("%s -N0 -o %s.ps %s" % (DVIPS_BINARY, self.doc, self.doc))
-
- def build_html(self, builddir, max_split_depth=None):
- if max_split_depth is None:
- max_split_depth = self.options.max_split_depth
- texfile = None
- for p in os.environ["TEXINPUTS"].split(os.pathsep):
- fn = os.path.join(p, self.doc + ".tex")
- if os.path.isfile(fn):
- texfile = fn
- break
- if not texfile:
- self.warning("Could not locate %s.tex; aborting." % self.doc)
- sys.exit(1)
- # remove leading ./ (or equiv.); might avoid problems w/ dvips
- if texfile[:2] == os.curdir + os.sep:
- texfile = texfile[2:]
- # build the command line and run LaTeX2HTML:
- if not os.path.isdir(builddir):
- os.mkdir(builddir)
- else:
- for fname in glob.glob(os.path.join(builddir, "*.html")):
- os.unlink(fname)
- args = [LATEX2HTML_BINARY,
- "-init_file", self.l2h_aux_init_file,
- "-dir", builddir,
- texfile
- ]
- self.run(" ".join(args)) # XXX need quoting!
- # ... postprocess
- shutil.copyfile(self.options.style_file,
- os.path.join(builddir, self.doc + ".css"))
- shutil.copyfile(os.path.join(builddir, self.doc + ".html"),
- os.path.join(builddir, "index.html"))
- if max_split_depth != 1:
- label_file = os.path.join(builddir, "labels.pl")
- fp = open(label_file)
- about_node = None
- target = " = q/about/;\n"
- x = len(target)
- while 1:
- line = fp.readline()
- if not line:
- break
- if line[-x:] == target:
- line = fp.readline()
- m = re.search(r"\|(node\d+\.[a-z]+)\|", line)
- about_node = m.group(1)
- shutil.copyfile(os.path.join(builddir, about_node),
- os.path.join(builddir, "about.html"))
- break
- if not self.options.numeric:
- pwd = os.getcwd()
- try:
- os.chdir(builddir)
- self.run("%s %s *.html" % (PERL_BINARY, NODE2LABEL_SCRIPT))
- finally:
- os.chdir(pwd)
- # These files need to be cleaned up here since builddir there
- # can be more than one, so we clean each of them.
- if self.options.discard_temps:
- for fn in ("images.tex", "images.log", "images.aux"):
- safe_unlink(os.path.join(builddir, fn))
-
- def build_text(self, tempdir=None):
- if tempdir is None:
- tempdir = self.doc
- indexfile = os.path.join(tempdir, "index.html")
- self.run("%s -nolist -dump %s >%s.txt"
- % (LYNX_BINARY, indexfile, self.doc))
-
- def require_temps(self, binary=None):
- if not self.latex_runs:
- self.build_aux(binary=binary)
-
- def write_l2h_aux_init_file(self):
- options = self.options
- fp = open(self.l2h_aux_init_file, "w")
- d = string_to_perl(os.path.dirname(L2H_INIT_FILE))
- fp.write("package main;\n"
- "push (@INC, '%s');\n"
- "$mydir = '%s';\n"
- % (d, d))
- fp.write(open(L2H_INIT_FILE).read())
- for filename in options.l2h_init_files:
- fp.write("\n# initialization code incorporated from:\n# ")
- fp.write(filename)
- fp.write("\n")
- fp.write(open(filename).read())
- fp.write("\n"
- "# auxillary init file for latex2html\n"
- "# generated by mkhowto\n"
- "$NO_AUTO_LINK = 1;\n"
- )
- l2hoption(fp, "ABOUT_FILE", options.about_file)
- l2hoption(fp, "ICONSERVER", options.icon_server)
- l2hoption(fp, "IMAGE_TYPE", options.image_type)
- l2hoption(fp, "ADDRESS", options.address)
- l2hoption(fp, "MAX_LINK_DEPTH", options.max_link_depth)
- l2hoption(fp, "MAX_SPLIT_DEPTH", options.max_split_depth)
- l2hoption(fp, "EXTERNAL_UP_LINK", options.up_link)
- l2hoption(fp, "EXTERNAL_UP_TITLE", options.up_title)
- l2hoption(fp, "FAVORITES_ICON", options.favicon)
- l2hoption(fp, "GLOBAL_MODULE_INDEX", options.global_module_index)
- l2hoption(fp, "DVIPS_SAFE", options.dvips_safe)
- fp.write("1;\n")
- fp.close()
-
- def cleanup(self):
- self.__have_temps = 0
- for pattern in ("%s.aux", "%s.log", "%s.out", "%s.toc", "%s.bkm",
- "%s.idx", "%s.ilg", "%s.ind", "%s.pla",
- "%s.bbl", "%s.blg",
- "mod%s.idx", "mod%s.ind", "mod%s.ilg",
- ):
- safe_unlink(pattern % self.doc)
- map(safe_unlink, glob.glob(self.doc + "*.syn"))
- for spec in ("IMG*", "*.pl", "WARNINGS", "index.dat", "modindex.dat"):
- pattern = os.path.join(self.doc, spec)
- map(safe_unlink, glob.glob(pattern))
- if "dvi" not in self.options.formats:
- safe_unlink(self.doc + ".dvi")
- if os.path.isdir(self.doc + "-temp-html"):
- shutil.rmtree(self.doc + "-temp-html", ignore_errors=1)
- if not self.options.logging:
- os.unlink(self.log_filename)
- if not self.options.debugging:
- os.unlink(self.l2h_aux_init_file)
-
- def run(self, command):
- self.message(command)
- if sys.platform.startswith("win"):
- rc = os.system(command)
- else:
- rc = os.system("(%s) </dev/null >>%s 2>&1"
- % (command, self.log_filename))
- if rc:
- self.warning(
- "Session transcript and error messages are in %s."
- % self.log_filename)
- result = 1
- if hasattr(os, "WIFEXITED"):
- if os.WIFEXITED(rc):
- result = os.WEXITSTATUS(rc)
- self.warning("Exited with status %s." % result)
- else:
- self.warning("Killed by signal %s." % os.WSTOPSIG(rc))
- else:
- self.warning("Return code: %s" % rc)
- sys.stderr.write("The relevant lines from the transcript are:\n")
- sys.stderr.write("-" * 72 + "\n")
- sys.stderr.writelines(get_run_transcript(self.log_filename))
- sys.exit(result)
-
- def message(self, msg):
- msg = "+++ " + msg
- if not self.options.quiet:
- print(msg)
- self.log(msg + "\n")
-
- def warning(self, msg):
- msg = "*** %s\n" % msg
- sys.stderr.write(msg)
- self.log(msg)
-
- def log(self, msg):
- fp = open(self.log_filename, "a")
- fp.write(msg)
- fp.close()
-
-
-def get_run_transcript(filename):
- """Return lines from the transcript file for the most recent run() call."""
- fp = open(filename)
- lines = fp.readlines()
- fp.close()
- lines.reverse()
- L = []
- for line in lines:
- L.append(line)
- if line[:4] == "+++ ":
- break
- L.reverse()
- return L
-
-
-def safe_unlink(path):
- """Unlink a file without raising an error if it doesn't exist."""
- try:
- os.unlink(path)
- except os.error:
- pass
-
-
-def split_pathname(path):
- path = os.path.abspath(path)
- dirname, basename = os.path.split(path)
- if basename[-4:] == ".tex":
- basename = basename[:-4]
- return dirname, basename
-
-
-_doctype_rx = re.compile(r"\\documentclass(?:\[[^]]*\])?{([a-zA-Z]*)}")
-def get_doctype(path):
- fp = open(path)
- doctype = None
- while 1:
- line = fp.readline()
- if not line:
- break
- m = _doctype_rx.match(line)
- if m:
- doctype = m.group(1)
- break
- fp.close()
- return doctype
-
-
-def main():
- options = Options()
- try:
- args = options.parse(sys.argv[1:])
- except getopt.error as msg:
- error(options, msg)
- if not args:
- # attempt to locate single .tex file in current directory:
- args = glob.glob("*.tex")
- if not args:
- error(options, "No file to process.")
- if len(args) > 1:
- error(options, "Could not deduce which files should be processed.")
- #
- # parameters are processed, let's go!
- #
- for path in args:
- Job(options, path).build()
-
-
-def l2hoption(fp, option, value):
- if value:
- fp.write('$%s = "%s";\n' % (option, string_to_perl(str(value))))
-
-
-_to_perl = {}
-for c in map(chr, range(1, 256)):
- _to_perl[c] = c
-_to_perl["@"] = "\\@"
-_to_perl["$"] = "\\$"
-_to_perl['"'] = '\\"'
-
-def string_to_perl(s):
- return ''.join(map(_to_perl.get, s))
-
-
-def check_for_bibtex(filename):
- fp = open(filename)
- pos = fp.read().find(r"\bibdata{")
- fp.close()
- return pos >= 0
-
-def uniqify_module_table(filename):
- lines = open(filename).readlines()
- if len(lines) > 1:
- if lines[-1] == lines[-2]:
- del lines[-1]
- open(filename, "w").writelines(lines)
-
-
-def new_index(filename, label="genindex"):
- fp = open(filename, "w")
- fp.write(r"""\
-\begin{theindex}
-\label{%s}
-\end{theindex}
-""" % label)
- fp.close()
-
-
-if __name__ == "__main__":
- main()
diff --git a/Doc/tools/mkinfo b/Doc/tools/mkinfo
deleted file mode 100755
index be75168..0000000
--- a/Doc/tools/mkinfo
+++ /dev/null
@@ -1,65 +0,0 @@
-#! /bin/sh
-# -*- Ksh -*-
-
-# Script to drive the HTML-info conversion process.
-# Pass in upto three parameters:
-# - the name of the main tex file
-# - the name of the output file in texi format (optional)
-# - the name of the output file in info format (optional)
-#
-# Written by Fred L. Drake, Jr. <fdrake@acm.org>
-
-EMACS=${EMACS:-emacs}
-MAKEINFO=${MAKEINFO:-makeinfo}
-
-
-# Normalize file name since something called by html2texi.pl seems to
-# screw up with relative path names.
-FILENAME="$1"
-DOCDIR=`dirname "$FILENAME"`
-DOCFILE=`basename "$FILENAME"`
-DOCNAME=`basename "$FILENAME" .tex`
-if [ $# -gt 1 ]; then
- TEXINAME="$2"
-else
- TEXINAME="python-$DOCNAME.texi"
-fi
-if [ $# -gt 2 ]; then
- INFONAME="$3"
-else
- INFONAME="python-$DOCNAME.info"
-fi
-
-# Now build the real directory names, and locate our support stuff:
-WORKDIR=`pwd`
-cd `dirname $0`
-TOOLSDIR=`pwd`
-cd $DOCDIR
-DOCDIR=`pwd`
-cd $WORKDIR
-
-COMMONDIR="`dirname $DOCDIR`/commontex"
-
-
-run() {
- # show what we're doing, like make does:
- echo "$*"
- "$@" || exit $?
-}
-
-
-# generate the Texinfo file:
-
-run $EMACS -batch -q --no-site-file -l $TOOLSDIR/py2texi.el \
- --eval "(setq py2texi-dirs '(\"$DOCDIR\" \"$COMMONDIR\" \"../texinputs\"))" \
- --eval "(setq py2texi-texi-file-name \"$TEXINAME\")" \
- --eval "(setq py2texi-info-file-name \"$INFONAME\")" \
- --eval "(py2texi \"$DOCDIR/$DOCFILE\")" \
- -f kill-emacs
-echo Done
-
-
-# generate the .info files:
-
-run $MAKEINFO --footnote-style end --fill-column 72 \
- --paragraph-indent 0 --output=$INFONAME $TEXINAME
diff --git a/Doc/tools/mkmodindex b/Doc/tools/mkmodindex
deleted file mode 100755
index cdc9d42..0000000
--- a/Doc/tools/mkmodindex
+++ /dev/null
@@ -1,158 +0,0 @@
-#! /usr/bin/env python
-# -*- Python -*-
-
-"""usage: %(program)s [options] file...
-
-Supported options:
-
- --address addr
- -a addr Set the address text to include at the end of the generated
- HTML; this should be used for contact information.
- --columns cols
- -c cols Set the number of columns each index section should be
- displayed in. The default is 1.
- --help
- -h Display this help message.
- --letters
- -l Split the output into sections by letter.
- --output file
- -o file Write output to 'file' instead of standard out.
- --iconserver is Use 'is' as the directory containing icons for the
- navigation bar. The default is 'icons'.
- --title str Set the page title to 'str'. The default is 'Global
- Module Index'.
- --uplink url Set the upward link URL. The default is './'.
- --uptitle str Set the upward link title. The default is 'Python
- Documentation Index'.
-"""
-import os
-import re
-import sys
-
-from xml.sax.saxutils import quoteattr
-
-import buildindex
-import support
-
-
-class IndexOptions(support.Options):
- aesop_type = "links"
-
- def __init__(self):
- support.Options.__init__(self)
- self.add_args("l", ["letters"])
- self.letters = 0
-
- def handle_option(self, opt, val):
- if opt in ("-l", "--letters"):
- self.letters = 1
-
- def usage(self):
- program = os.path.basename(sys.argv[0])
- print(__doc__ % {"program": program})
-
- links = [
- ('author', 'acks.html', 'Acknowledgements'),
- ('help', 'about.html', 'About the Python Documentation'),
- ]
-
- def get_header(self):
- header = support.Options.get_header(self)
- s = ''
- for rel, href, title in self.links:
- s += '<link rel="%s" href="%s"' % (rel, href)
- if title:
- s += ' title=' + quoteattr(title)
- s += '>\n '
- return header.replace("<link ", s + "<link ", 1)
-
-
-class Node(buildindex.Node):
- def __init__(self, link, str, seqno, platinfo):
- self.annotation = platinfo or None
- if str[0][-5:] == "</tt>":
- str = str[:-5]
- self.modname = str
- buildindex.Node.__init__(self, link, self.modname, seqno)
- if platinfo:
- s = '<tt class="module">%s</tt> %s' \
- % (self.modname, self.annotation)
- else:
- s = '<tt class="module">%s</tt>' % str
- self.text = [s]
-
- def __str__(self):
- if self.annotation:
- return '<tt class="module">%s</tt> %s' \
- % (self.modname, self.annotation)
- else:
- return '<tt class="module">%s</tt>' % self.modname
-
-_rx = re.compile(
- "<dt><a href=['\"](module-.*\.html)(?:#l2h-\d+)?['\"]>"
- "<tt class=['\"]module['\"]>([a-zA-Z_][a-zA-Z0-9_.]*)</tt>\s*(<em>"
- "\(<span class=['\"]platform['\"]>.*</span>\)</em>)?</a>")
-
-def main():
- options = IndexOptions()
- options.variables["title"] = "Global Module Index"
- options.parse(sys.argv[1:])
- args = options.args
- if not args:
- args = ["-"]
- #
- # Collect the input data:
- #
- nodes = []
- has_plat_flag = 0
- for ifn in args:
- if ifn == "-":
- ifp = sys.stdin
- dirname = ''
- else:
- ifp = open(ifn)
- dirname = os.path.dirname(ifn)
- while 1:
- line = ifp.readline()
- if not line:
- break
- m = _rx.match(line)
- if m:
- # This line specifies a module!
- basename, modname, platinfo = m.group(1, 2, 3)
- has_plat_flag = has_plat_flag or platinfo
- linkfile = os.path.join(dirname, basename)
- nodes.append(Node('<a href="%s">' % linkfile, modname,
- len(nodes), platinfo))
- ifp.close()
- #
- # Generate all output:
- #
- num_nodes = len(nodes)
- # Here's the HTML generation:
- parts = [options.get_header(),
- buildindex.process_nodes(nodes, options.columns, options.letters),
- options.get_footer(),
- ]
- if has_plat_flag:
- parts.insert(1, PLAT_DISCUSS)
- html = ''.join(parts)
- program = os.path.basename(sys.argv[0])
- fp = options.get_output_file()
- fp.write(html.rstrip() + "\n")
- if options.outputfile == "-":
- sys.stderr.write("%s: %d index nodes\n" % (program, num_nodes))
- else:
- print()
- print("%s: %d index nodes" % (program, num_nodes))
-
-
-PLAT_DISCUSS = """
-<p> Some module names are followed by an annotation indicating what
-platform they are available on.</p>
-
-"""
-
-
-if __name__ == "__main__":
- main()
diff --git a/Doc/tools/mkpkglist b/Doc/tools/mkpkglist
deleted file mode 100755
index 1a1fd78..0000000
--- a/Doc/tools/mkpkglist
+++ /dev/null
@@ -1,85 +0,0 @@
-#! /usr/bin/env python
-#
-# Simple script to create the table that lists the packages available
-# for download. This expects the downloadable files and the Makefile
-# to be in the current directory.
-#
-# The output of this script can be pasted directly into the download
-# page for the documentation.
-
-import os
-import sys
-
-from os.path import isfile
-
-
-PKG_TYPES = [
- # human name, filename prefix
- ("HTML", "html"),
- ("PDF (US-Letter)", "pdf-letter"),
- ("PDF (A4)", "pdf-a4"),
- ("PostScript (US-Letter)", "postscript-letter"),
- ("PostScript (A4)", "postscript-a4"),
- ("GNU info", "info"),
- ("iSilo", "isilo"),
- ("LaTeX", "latex"),
- ]
-
-getversioninfo = os.path.join(os.path.dirname(__file__), "getversioninfo")
-fp = os.popen('"%s" "%s"' % (sys.executable, getversioninfo), "r")
-release = fp.readline().strip()
-fp.close()
-
-print '''\
-<table border="1" cellpadding="3" align="center">
- <thead>
- <tr bgcolor="#99ccff"><th rowspan="2">Content</th>
- <th colspan="3">Format</th></tr>
- <tr bgcolor="#99ccff"><th>ZIP</th><th>GZip</th><th>BZip2</th></tr>
- </thead>
- <tbody>'''
-
-# formatted using FILE_TEMPLATE % (release, prefix, release, extension)
-FILE_TEMPLATE = '''\
- <td><a href="../../ftp/python/doc/%s/%s-%s%s"
- >%dK</a></td>'''
-
-NO_FILE_TEMPLATE = '''\
- <td>&nbsp;</td>'''
-
-def get_size(prefix, ext):
- fn = "%s-%s%s" % (prefix, release, ext)
- return int(round(os.path.getsize(fn) / 1024.0))
-
-def get_file_cell(prefix, ext, have):
- if have:
- kb = get_size(prefix, ext)
- return FILE_TEMPLATE % (release, prefix, release, ext, kb)
- else:
- return NO_FILE_TEMPLATE
-
-for name, prefix in PKG_TYPES:
- zip_fn = "%s-%s.zip" % (prefix, release)
- tgz_fn = "%s-%s.tgz" % (prefix, release)
- bz2_fn = "%s-%s.tar.bz2" % (prefix, release)
-
- have_zip = isfile(zip_fn)
- have_tgz = isfile(tgz_fn)
- have_bz2 = isfile(bz2_fn)
-
- have_some = have_zip or have_tgz or have_bz2
-
- if not have_some:
- print " <!--"
- print " <tr><td>%s</td>" % name
- print get_file_cell(prefix, ".zip", have_zip)
- print get_file_cell(prefix, ".tgz", have_tgz)
- print get_file_cell(prefix, ".tar.bz2", have_bz2)
- print " </tr>"
- if not have_some:
- print " -->"
-
-print '''\
- </tbody>
-</table>
-'''
diff --git a/Doc/tools/mksourcepkg b/Doc/tools/mksourcepkg
deleted file mode 100755
index 7d5bd73..0000000
--- a/Doc/tools/mksourcepkg
+++ /dev/null
@@ -1,164 +0,0 @@
-#! /usr/bin/env python
-# -*- Python -*-
-
-"""%(program)s - script to create the latex source distribution
-
-usage:
- %(program)s [-t|--tools] release [tag]
-
-with -t|--tools: doesn't include the documents, only the framework
-
-without [tag]: generate from the current version that's checked in
- (*NOT* what's in the current directory!)
-
-with [tag]: generate from the named tag
-"""
-#* should be modified to get the Python version number automatically
-# from the Makefile or someplace.
-
-import getopt
-import glob
-import os
-import re
-import shutil
-import sys
-import tempfile
-
-try:
- __file__
-except NameError:
- __file__ = sys.argv[0]
-
-tools = os.path.dirname(os.path.abspath(__file__))
-Doc = os.path.dirname(tools)
-patchlevel_tex = os.path.join(Doc, "commontex", "patchlevel.tex")
-
-quiet = 0
-rx = re.compile(r":ext:(?:[a-zA-Z0-9]+@)?cvs\.([a-zA-Z0-9]+).sourceforge.net:"
- r"/cvsroot/\1")
-
-
-def main():
- global quiet
- anonymous = False
- try:
- opts, args = getopt.getopt(sys.argv[1:], "Aabgtzq",
- ["all", "bzip2", "gzip", "tools", "zip",
- "quiet", "anonymous"])
- except getopt.error as e:
- usage(warning=str(e))
- sys.exit(2)
- if len(args) not in (1, 2):
- usage(warning="wrong number of parameters")
- sys.exit(2)
- tools = 0
- formats = {}
- for opt, arg in opts:
- if opt in ("-t", "--tools"):
- tools = 1
- elif opt in ("-q", "--quiet"):
- quiet = quiet + 1
- elif opt in ("-b", "--bzip2"):
- formats["bzip2"] = 1
- elif opt in ("-g", "--gzip"):
- formats["gzip"] = 1
- elif opt in ("-z", "--zip"):
- formats["zip"] = 1
- elif opt in ("-a", "--all"):
- formats["bzip2"] = 1
- formats["gzip"] = 1
- formats["zip"] = 1
- elif opt in ("-A", "--anonymous"):
- anonymous = True
- if formats:
- # make order human-predictable
- formats = formats.keys()
- formats.sort()
- else:
- formats = ["gzip"]
- release = args[0]
- svntag = None
- if len(args) > 1:
- svntag = args[1]
- tempdir = tempfile.mktemp()
- os.mkdir(tempdir)
- pkgdir = os.path.join(tempdir, "Python-Docs-" + release)
- pwd = os.getcwd()
- mydir = os.path.abspath(os.path.dirname(sys.argv[0]))
- os.chdir(tempdir)
- if not quiet:
- print "--- current directory is:", tempdir
- if not svntag:
- svntag = "trunk"
- svnbase = "http://svn.python.org/projects/python"
- run("svn export %s/%s/Doc Python-Docs-%s"
- % (svnbase, svntag, release))
-
- # Copy in the version informtation, if we're not just going to
- # rip it back out:
- if not tools:
- if not os.path.exists(patchlevel_tex):
- run(os.path.join(here, "getversioninfo"))
- dest = os.path.join("Python-Docs-" + release, "commontex",
- "patchlevel.tex")
- shutil.copyfile(patchlevel_tex, dest)
-
- # Copy in the license file:
- LICENSE = os.path.normpath(
- os.path.join(mydir, os.pardir, os.pardir, "LICENSE"))
- shutil.copyfile(LICENSE, "LICENSE")
- if tools:
- archive = "doctools-" + release
- # we don't want the actual documents in this case:
- for d in ("api", "dist", "doc", "ext", "inst",
- "lib", "mac", "ref", "tut", "commontex"):
- shutil.rmtree(os.path.join(pkgdir, d))
- else:
- archive = "latex-" + release
-
- # XXX should also remove the .cvsignore files at this point
-
- os.chdir(tempdir)
- archive = os.path.join(pwd, archive)
- for format in formats:
- if format == "bzip2":
- run("tar cf - Python-Docs-%s | bzip2 -9 >%s.tar.bz2"
- % (release, archive))
- elif format == "gzip":
- run("tar cf - Python-Docs-%s | gzip -9 >%s.tgz"
- % (release, archive))
- elif format == "zip":
- if os.path.exists(archive + ".zip"):
- os.unlink(archive + ".zip")
- run("zip -q -r9 %s.zip Python-Docs-%s"
- % (archive, release))
-
- # clean up the work area:
- os.chdir(pwd)
- shutil.rmtree(tempdir)
-
-
-def run(cmd):
- if quiet < 2:
- print "+++", cmd
- if quiet:
- cmd = "%s >/dev/null" % cmd
- rc = os.system(cmd)
- if rc:
- sys.exit(rc)
-
-
-def usage(warning=None):
- stdout = sys.stdout
- sys.stdout = sys.stderr
- program = os.path.basename(sys.argv[0])
- try:
- if warning:
- print "%s: %s\n" % (program, warning)
- print __doc__ % {"program": program}
- finally:
- sys.stdout = stdout
-
-
-if __name__ == "__main__":
- main()
diff --git a/Doc/tools/node2label.pl b/Doc/tools/node2label.pl
deleted file mode 100755
index 6491b20..0000000
--- a/Doc/tools/node2label.pl
+++ /dev/null
@@ -1,71 +0,0 @@
-#! /usr/bin/env perl
-
-# On Cygwin, we actually have to generate a temporary file when doing
-# the inplace edit, or we'll get permission errors. Not sure who's
-# bug this is, except that it isn't ours. To deal with this, we
-# generate backups during the edit phase and remove them at the end.
-#
-use English;
-$INPLACE_EDIT = '.bak';
-
-# read the labels, then reverse the mappings
-require "labels.pl";
-
-%nodes = ();
-my $key;
-# sort so that we get a consistent assignment for nodes with multiple labels
-foreach $label (sort keys %external_labels) {
- #
- # If the label can't be used as a filename on non-Unix platforms,
- # skip it. Such labels may be used internally within the documentation,
- # but will never be used for filename generation.
- #
- if ($label =~ /^([-.a-zA-Z0-9]+)$/) {
- $key = $external_labels{$label};
- $key =~ s|^/||;
- $nodes{$key} = $label;
- }
-}
-
-# This adds the "internal" labels added for indexing. These labels will not
-# be used for file names.
-require "intlabels.pl";
-foreach $label (keys %internal_labels) {
- $key = $internal_labels{$label};
- $key =~ s|^/||;
- if (defined($nodes{$key})) {
- $nodes{$label} = $nodes{$key};
- }
-}
-
-# collect labels that have been used
-%newnames = ();
-
-while (<>) {
- # don't want to do one s/// per line per node
- # so look for lines with hrefs, then do s/// on nodes present
- if (/(HREF|href)=[\"\']node\d+\.html[\#\"\']/) {
- @parts = split(/(HREF|href)\=[\"\']/);
- shift @parts;
- for $node (@parts) {
- $node =~ s/[\#\"\'].*$//g;
- chomp($node);
- if (defined($nodes{$node})) {
- $label = $nodes{$node};
- if (s/(HREF|href)=([\"\'])$node([\#\"\'])/href=$2$label.html$3/g) {
- s/(HREF|href)=([\"\'])$label.html/href=$2$label.html/g;
- $newnames{$node} = "$label.html";
- }
- }
- }
- }
- print;
-}
-
-foreach $oldname (keys %newnames) {
- rename($oldname, $newnames{$oldname});
-}
-
-foreach $filename (glob('*.bak')) {
- unlink($filename);
-}
diff --git a/Doc/tools/prechm.py b/Doc/tools/prechm.py
deleted file mode 100644
index b24eea0..0000000
--- a/Doc/tools/prechm.py
+++ /dev/null
@@ -1,519 +0,0 @@
-"""
- Makes the necesary files to convert from plain html of
- Python 1.5 and 1.5.x Documentation to
- Microsoft HTML Help format version 1.1
- Doesn't change the html's docs.
-
- by hernan.foffani@iname.com
- no copyright and no responsabilities.
-
- modified by Dale Nagata for Python 1.5.2
-
- Renamed from make_chm.py to prechm.py, and checked into the Python
- project, 19-Apr-2002 by Tim Peters. Assorted modifications by Tim
- and Fred Drake. Obtained from Robin Dunn's .chm packaging of the
- Python 2.2 docs, at <http://alldunn.com/python/>.
-"""
-
-import sys
-import os
-from formatter import NullWriter, AbstractFormatter
-from htmllib import HTMLParser
-import getopt
-import cgi
-
-usage_mode = '''
-Usage: prechm.py [-c] [-k] [-p] [-v 1.5[.x]] filename
- -c: does not build filename.hhc (Table of Contents)
- -k: does not build filename.hhk (Index)
- -p: does not build filename.hhp (Project File)
- -v 1.5[.x]: makes help for the python 1.5[.x] docs
- (default is python 1.5.2 docs)
-'''
-
-# Project file (*.hhp) template. 'arch' is the file basename (like
-# the pythlp in pythlp.hhp); 'version' is the doc version number (like
-# the 2.2 in Python 2.2).
-# The magical numbers in the long line under [WINDOWS] set most of the
-# user-visible features (visible buttons, tabs, etc).
-# About 0x10384e: This defines the buttons in the help viewer. The
-# following defns are taken from htmlhelp.h. Not all possibilities
-# actually work, and not all those that work are available from the Help
-# Workshop GUI. In particular, the Zoom/Font button works and is not
-# available from the GUI. The ones we're using are marked with 'x':
-#
-# 0x000002 Hide/Show x
-# 0x000004 Back x
-# 0x000008 Forward x
-# 0x000010 Stop
-# 0x000020 Refresh
-# 0x000040 Home x
-# 0x000080 Forward
-# 0x000100 Back
-# 0x000200 Notes
-# 0x000400 Contents
-# 0x000800 Locate x
-# 0x001000 Options x
-# 0x002000 Print x
-# 0x004000 Index
-# 0x008000 Search
-# 0x010000 History
-# 0x020000 Favorites
-# 0x040000 Jump 1
-# 0x080000 Jump 2
-# 0x100000 Zoom/Font x
-# 0x200000 TOC Next
-# 0x400000 TOC Prev
-
-project_template = '''
-[OPTIONS]
-Compiled file=%(arch)s.chm
-Contents file=%(arch)s.hhc
-Default Window=%(arch)s
-Default topic=index.html
-Display compile progress=No
-Full text search stop list file=%(arch)s.stp
-Full-text search=Yes
-Index file=%(arch)s.hhk
-Language=0x409
-Title=Python %(version)s Documentation
-
-[WINDOWS]
-%(arch)s="Python %(version)s Documentation","%(arch)s.hhc","%(arch)s.hhk",\
-"index.html","index.html",,,,,0x63520,220,0x10384e,[0,0,1024,768],,,,,,,0
-
-[FILES]
-'''
-
-contents_header = '''\
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<HTML>
-<HEAD>
-<meta name="GENERATOR" content="Microsoft&reg; HTML Help Workshop 4.1">
-<!-- Sitemap 1.0 -->
-</HEAD><BODY>
-<OBJECT type="text/site properties">
- <param name="Window Styles" value="0x801227">
- <param name="ImageType" value="Folder">
-</OBJECT>
-<UL>
-'''
-
-contents_footer = '''\
-</UL></BODY></HTML>
-'''
-
-object_sitemap = '''\
-<OBJECT type="text/sitemap">
- <param name="Name" value="%s">
- <param name="Local" value="%s">
-</OBJECT>
-'''
-
-# List of words the full text search facility shouldn't index. This
-# becomes file ARCH.stp. Note that this list must be pretty small!
-# Different versions of the MS docs claim the file has a maximum size of
-# 256 or 512 bytes (including \r\n at the end of each line).
-# Note that "and", "or", "not" and "near" are operators in the search
-# language, so no point indexing them even if we wanted to.
-stop_list = '''
-a and are as at
-be but by
-for
-if in into is it
-near no not
-of on or
-such
-that the their then there these they this to
-was will with
-'''
-
-# s is a string or None. If None or empty, return None. Else tack '.html'
-# on to the end, unless it's already there.
-def addhtml(s):
- if s:
- if not s.endswith('.html'):
- s += '.html'
- return s
-
-# Convenience class to hold info about "a book" in HTMLHelp terms == a doc
-# directory in Python terms.
-class Book:
- def __init__(self, directory, title, firstpage,
- contentpage=None, indexpage=None):
- self.directory = directory
- self.title = title
- self.firstpage = addhtml(firstpage)
- self.contentpage = addhtml(contentpage)
- self.indexpage = addhtml(indexpage)
-
-# Library Doc list of books:
-# each 'book' : (Dir, Title, First page, Content page, Index page)
-supported_libraries = {
- '2.5':
- [
- Book('.', 'Main page', 'index'),
- Book('.', 'Global Module Index', 'modindex'),
- Book('whatsnew', "What's New", 'index', 'contents'),
- Book('tut','Tutorial','tut','node2'),
- Book('lib','Library Reference','lib','contents','genindex'),
- Book('ref','Language Reference','ref','contents','genindex'),
- Book('mac','Macintosh Reference','mac','contents','genindex'),
- Book('ext','Extending and Embedding','ext','contents'),
- Book('api','Python/C API','api','contents','genindex'),
- Book('doc','Documenting Python','doc','contents'),
- Book('inst','Installing Python Modules', 'inst', 'index'),
- Book('dist','Distributing Python Modules', 'dist', 'index', 'genindex'),
- ],
-
- '2.4':
- [
- Book('.', 'Main page', 'index'),
- Book('.', 'Global Module Index', 'modindex'),
- Book('whatsnew', "What's New", 'index', 'contents'),
- Book('tut','Tutorial','tut','node2'),
- Book('lib','Library Reference','lib','contents','genindex'),
- Book('ref','Language Reference','ref','contents','genindex'),
- Book('mac','Macintosh Reference','mac','contents','genindex'),
- Book('ext','Extending and Embedding','ext','contents'),
- Book('api','Python/C API','api','contents','genindex'),
- Book('doc','Documenting Python','doc','contents'),
- Book('inst','Installing Python Modules', 'inst', 'index'),
- Book('dist','Distributing Python Modules', 'dist', 'index', 'genindex'),
- ],
-
- '2.3':
- [
- Book('.', 'Main page', 'index'),
- Book('.', 'Global Module Index', 'modindex'),
- Book('whatsnew', "What's New", 'index', 'contents'),
- Book('tut','Tutorial','tut','node2'),
- Book('lib','Library Reference','lib','contents','genindex'),
- Book('ref','Language Reference','ref','contents','genindex'),
- Book('mac','Macintosh Reference','mac','contents','genindex'),
- Book('ext','Extending and Embedding','ext','contents'),
- Book('api','Python/C API','api','contents','genindex'),
- Book('doc','Documenting Python','doc','contents'),
- Book('inst','Installing Python Modules', 'inst', 'index'),
- Book('dist','Distributing Python Modules', 'dist', 'index'),
- ],
-
- '2.2':
- [
- Book('.', 'Main page', 'index'),
- Book('.', 'Global Module Index', 'modindex'),
- Book('whatsnew', "What's New", 'index', 'contents'),
- Book('tut','Tutorial','tut','node2'),
- Book('lib','Library Reference','lib','contents','genindex'),
- Book('ref','Language Reference','ref','contents','genindex'),
- Book('mac','Macintosh Reference','mac','contents','genindex'),
- Book('ext','Extending and Embedding','ext','contents'),
- Book('api','Python/C API','api','contents','genindex'),
- Book('doc','Documenting Python','doc','contents'),
- Book('inst','Installing Python Modules', 'inst', 'index'),
- Book('dist','Distributing Python Modules', 'dist', 'index'),
- ],
-
- '2.1.1':
- [
- Book('.', 'Main page', 'index'),
- Book('.', 'Global Module Index', 'modindex'),
- Book('tut','Tutorial','tut','node2'),
- Book('lib','Library Reference','lib','contents','genindex'),
- Book('ref','Language Reference','ref','contents','genindex'),
- Book('mac','Macintosh Reference','mac','contents','genindex'),
- Book('ext','Extending and Embedding','ext','contents'),
- Book('api','Python/C API','api','contents','genindex'),
- Book('doc','Documenting Python','doc','contents'),
- Book('inst','Installing Python Modules', 'inst', 'index'),
- Book('dist','Distributing Python Modules', 'dist', 'index'),
- ],
-
- '2.0.0':
- [
- Book('.', 'Global Module Index', 'modindex'),
- Book('tut','Tutorial','tut','node2'),
- Book('lib','Library Reference','lib','contents','genindex'),
- Book('ref','Language Reference','ref','contents','genindex'),
- Book('mac','Macintosh Reference','mac','contents','genindex'),
- Book('ext','Extending and Embedding','ext','contents'),
- Book('api','Python/C API','api','contents','genindex'),
- Book('doc','Documenting Python','doc','contents'),
- Book('inst','Installing Python Modules', 'inst', 'contents'),
- Book('dist','Distributing Python Modules', 'dist', 'contents'),
- ],
-
- # <dnagata@creo.com> Apr 17/99: library for 1.5.2 version:
- # <hernan.foffani@iname.com> May 01/99: library for 1.5.2 (04/30/99):
- '1.5.2':
- [
- Book('tut','Tutorial','tut','node2'),
- Book('lib','Library Reference','lib','contents','genindex'),
- Book('ref','Language Reference','ref','contents','genindex'),
- Book('mac','Macintosh Reference','mac','contents','genindex'),
- Book('ext','Extending and Embedding','ext','contents'),
- Book('api','Python/C API','api','contents','genindex'),
- Book('doc','Documenting Python','doc','contents')
- ],
-
- # library for 1.5.1 version:
- '1.5.1':
- [
- Book('tut','Tutorial','tut','contents'),
- Book('lib','Library Reference','lib','contents','genindex'),
- Book('ref','Language Reference','ref-1','ref-2','ref-11'),
- Book('ext','Extending and Embedding','ext','contents'),
- Book('api','Python/C API','api','contents','genindex')
- ],
-
- # library for 1.5 version:
- '1.5':
- [
- Book('tut','Tutorial','tut','node1'),
- Book('lib','Library Reference','lib','node1','node268'),
- Book('ref','Language Reference','ref-1','ref-2','ref-11'),
- Book('ext','Extending and Embedding','ext','node1'),
- Book('api','Python/C API','api','node1','node48')
- ]
-}
-
-# AlmostNullWriter doesn't print anything; it just arranges to save the
-# text sent to send_flowing_data(). This is used to capture the text
-# between an anchor begin/end pair, e.g. for TOC entries.
-
-class AlmostNullWriter(NullWriter):
-
- def __init__(self):
- NullWriter.__init__(self)
- self.saved_clear()
-
- def send_flowing_data(self, data):
- stripped = data.strip()
- if stripped: # don't bother to save runs of whitespace
- self.saved.append(stripped)
-
- # Forget all saved text.
- def saved_clear(self):
- self.saved = []
-
- # Return all saved text as a string.
- def saved_get(self):
- return ' '.join(self.saved)
-
-class HelpHtmlParser(HTMLParser):
-
- def __init__(self, formatter, path, output):
- HTMLParser.__init__(self, formatter)
- self.path = path # relative path
- self.ft = output # output file
- self.indent = 0 # number of tabs for pretty printing of files
- self.proc = False # True when actively processing, else False
- # (headers, footers, etc)
- # XXX This shouldn't need to be a stack -- anchors shouldn't nest.
- # XXX See SF bug <http://www.python.org/sf/546579>.
- self.hrefstack = [] # stack of hrefs from anchor begins
-
- def begin_group(self):
- self.indent += 1
- self.proc = True
-
- def finish_group(self):
- self.indent -= 1
- # stop processing when back to top level
- self.proc = self.indent > 0
-
- def anchor_bgn(self, href, name, type):
- if self.proc:
- # XXX See SF bug <http://www.python.org/sf/546579>.
- # XXX index.html for the 2.2.1 language reference manual contains
- # XXX nested <a></a> tags in the entry for the section on blank
- # XXX lines. We want to ignore the nested part completely.
- if len(self.hrefstack) == 0:
- self.saved_clear()
- self.hrefstack.append(href)
-
- def anchor_end(self):
- if self.proc:
- # XXX See XXX above.
- if self.hrefstack:
- title = cgi.escape(self.saved_get(), True)
- path = self.path + '/' + self.hrefstack.pop()
- self.tab(object_sitemap % (title, path))
-
- def start_dl(self, atr_val):
- self.begin_group()
-
- def end_dl(self):
- self.finish_group()
-
- def do_dt(self, atr_val):
- # no trailing newline on purpose!
- self.tab("<LI>")
-
- # Write text to output file.
- def write(self, text):
- self.ft.write(text)
-
- # Write text to output file after indenting by self.indent tabs.
- def tab(self, text=''):
- self.write('\t' * self.indent)
- if text:
- self.write(text)
-
- # Forget all saved text.
- def saved_clear(self):
- self.formatter.writer.saved_clear()
-
- # Return all saved text as a string.
- def saved_get(self):
- return self.formatter.writer.saved_get()
-
-class IdxHlpHtmlParser(HelpHtmlParser):
- # nothing special here, seems enough with parent class
- pass
-
-class TocHlpHtmlParser(HelpHtmlParser):
-
- def start_dl(self, atr_val):
- self.begin_group()
- self.tab('<UL>\n')
-
- def end_dl(self):
- self.finish_group()
- self.tab('</UL>\n')
-
- def start_ul(self, atr_val):
- self.begin_group()
- self.tab('<UL>\n')
-
- def end_ul(self):
- self.finish_group()
- self.tab('</UL>\n')
-
- def do_li(self, atr_val):
- # no trailing newline on purpose!
- self.tab("<LI>")
-
-def index(path, indexpage, output):
- parser = IdxHlpHtmlParser(AbstractFormatter(AlmostNullWriter()),
- path, output)
- f = open(path + '/' + indexpage)
- parser.feed(f.read())
- parser.close()
- f.close()
-
-def content(path, contentpage, output):
- parser = TocHlpHtmlParser(AbstractFormatter(AlmostNullWriter()),
- path, output)
- f = open(path + '/' + contentpage)
- parser.feed(f.read())
- parser.close()
- f.close()
-
-def do_index(library, output):
- output.write('<UL>\n')
- for book in library:
- print('\t', book.title, '-', book.indexpage)
- if book.indexpage:
- index(book.directory, book.indexpage, output)
- output.write('</UL>\n')
-
-def do_content(library, version, output):
- output.write(contents_header)
- for book in library:
- print('\t', book.title, '-', book.firstpage)
- path = book.directory + "/" + book.firstpage
- output.write('<LI>')
- output.write(object_sitemap % (book.title, path))
- if book.contentpage:
- content(book.directory, book.contentpage, output)
- output.write(contents_footer)
-
-# Fill in the [FILES] section of the project (.hhp) file.
-# 'library' is the list of directory description tuples from
-# supported_libraries for the version of the docs getting generated.
-def do_project(library, output, arch, version):
- output.write(project_template % locals())
- pathseen = {}
- for book in library:
- directory = book.directory
- path = directory + '\\%s\n'
- for page in os.listdir(directory):
- if page.endswith('.html') or page.endswith('.css'):
- fullpath = path % page
- if fullpath not in pathseen:
- output.write(fullpath)
- pathseen[fullpath] = True
-
-def openfile(file):
- try:
- p = open(file, "w")
- except IOError as msg:
- print(file, ":", msg)
- sys.exit(1)
- return p
-
-def usage():
- print(usage_mode)
- sys.exit(0)
-
-def do_it(args = None):
- if not args:
- args = sys.argv[1:]
-
- if not args:
- usage()
-
- try:
- optlist, args = getopt.getopt(args, 'ckpv:')
- except getopt.error as msg:
- print(msg)
- usage()
-
- if not args or len(args) > 1:
- usage()
- arch = args[0]
-
- version = None
- for opt in optlist:
- if opt[0] == '-v':
- version = opt[1]
- break
- if not version:
- usage()
-
- library = supported_libraries[version]
-
- if not (('-p','') in optlist):
- fname = arch + '.stp'
- f = openfile(fname)
- print("Building stoplist", fname, "...")
- words = stop_list.split()
- words.sort()
- for word in words:
- print(word, file=f)
- f.close()
-
- f = openfile(arch + '.hhp')
- print("Building Project...")
- do_project(library, f, arch, version)
- if version == '2.0.0':
- for image in os.listdir('icons'):
- f.write('icons'+ '\\' + image + '\n')
-
- f.close()
-
- if not (('-c','') in optlist):
- f = openfile(arch + '.hhc')
- print("Building Table of Content...")
- do_content(library, version, f)
- f.close()
-
- if not (('-k','') in optlist):
- f = openfile(arch + '.hhk')
- print("Building Index...")
- do_index(library, f)
- f.close()
-
-if __name__ == '__main__':
- do_it()
diff --git a/Doc/tools/push-docs.sh b/Doc/tools/push-docs.sh
deleted file mode 100755
index 28a4b31..0000000
--- a/Doc/tools/push-docs.sh
+++ /dev/null
@@ -1,138 +0,0 @@
-#! /bin/sh
-
-# Script to push docs from my development area to SourceForge, where the
-# update-docs.sh script unpacks them into their final destination.
-
-TARGETHOST=www.python.org
-TARGETDIR=/usr/home/fdrake/tmp
-
-PKGTYPE="bzip" # must be one of: bzip, tar, zip ("tar" implies gzip)
-
-TARGET="$TARGETHOST:$TARGETDIR"
-
-ADDRESSES='python-dev@python.org doc-sig@python.org python-list@python.org'
-
-TOOLDIR="`dirname $0`"
-VERSION=`$TOOLDIR/getversioninfo`
-
-# Set $EXTRA to something non-empty if this is a non-trunk version:
-EXTRA=`echo "$VERSION" | sed 's/^[0-9][0-9]*\.[0-9][0-9]*//'`
-
-if echo "$EXTRA" | grep -q '[.]' ; then
- DOCLABEL="maintenance"
- DOCTYPE="maint"
-else
- DOCLABEL="development"
- DOCTYPE="devel"
-fi
-
-DOCTYPE_SPECIFIED=false
-EXPLANATION=''
-ANNOUNCE=true
-
-getopt -T >/dev/null
-if [ $? -eq 4 ] ; then
- # We have a sufficiently useful getopt(1) implementation.
- eval "set -- `getopt -ssh m:p:qt:F: \"$@\"`"
-else
- # This version of getopt doesn't support quoting of long options
- # with spaces, so let's not rely on it at all.
- :
-fi
-
-while [ "$#" -gt 0 ] ; do
- case "$1" in
- -m)
- EXPLANATION="$2"
- shift 2
- ;;
- -p)
- PKGTYPE="$2"
- shift 1
- ;;
- -q)
- ANNOUNCE=false
- shift 1
- ;;
- -t)
- DOCTYPE="$2"
- DOCTYPE_SPECIFIED=true
- shift 2
- ;;
- -F)
- EXPLANATION="`cat $2`"
- shift 2
- ;;
- --)
- shift 1
- break
- ;;
- -*)
- echo "Unknown option: $1" >&2
- exit 2
- ;;
- *)
- break
- ;;
- esac
-done
-if [ "$1" ] ; then
- if [ "$EXPLANATION" ] ; then
- echo "Explanation may only be given once!" >&2
- exit 2
- fi
- EXPLANATION="$1"
- shift
-fi
-
-START="`pwd`"
-MYDIR="`dirname $0`"
-cd "$MYDIR"
-MYDIR="`pwd`"
-
-if [ "$PKGTYPE" = bzip ] ; then
- PKGEXT=tar.bz2
-elif [ "$PKGTYPE" = tar ] ; then
- PKGEXT=tgz
-elif [ "$PKGTYPE" = zip ] ; then
- PKGEXT=zip
-else
- echo 1>&2 "unsupported package type: $PKGTYPE"
- exit 2
-fi
-
-# switch to .../Doc/
-cd ..
-
-# If $DOCTYPE was not specified explicitly, look for .doctype in
-# .../Doc/ and use the content of that file if present.
-if $DOCTYPE_SPECIFIED ; then
- :
-elif [ -f .doctype ] ; then
- DOCTYPE="`cat .doctype`"
-fi
-
-make --no-print-directory ${PKGTYPE}html || exit $?
-PACKAGE="html-$VERSION.$PKGEXT"
-scp "$PACKAGE" tools/update-docs.sh $TARGET/ || exit $?
-ssh "$TARGETHOST" tmp/update-docs.sh $DOCTYPE $PACKAGE '&&' rm tmp/update-docs.sh || exit $?
-
-if $ANNOUNCE ; then
- sendmail $ADDRESSES <<EOF
-To: $ADDRESSES
-From: "Fred L. Drake" <fdrake@acm.org>
-Subject: [$DOCLABEL doc updates]
-X-No-Archive: yes
-
-The $DOCLABEL version of the documentation has been updated:
-
- http://$TARGETHOST/dev/doc/$DOCTYPE/
-
-$EXPLANATION
-
-A downloadable package containing the HTML is also available:
-
- http://$TARGETHOST/dev/doc/python-docs-$DOCTYPE.$PKGEXT
-EOF
- exit $?
-fi
diff --git a/Doc/tools/py2texi.el b/Doc/tools/py2texi.el
deleted file mode 100644
index 404234f..0000000
--- a/Doc/tools/py2texi.el
+++ /dev/null
@@ -1,970 +0,0 @@
-;;; py2texi.el -- Conversion of Python LaTeX documentation to Texinfo
-
-;; Copyright (C) 2006 Jeroen Dekkers <jeroen@dekkers.cx>
-;; Copyright (C) 1998, 1999, 2001, 2002 Milan Zamazal
-
-;; Author: Milan Zamazal <pdm@zamazal.org>
-;; Version: $Id$
-;; Keywords: python
-
-;; COPYRIGHT NOTICE
-;;
-;; This program is free software; you can redistribute it and/or modify it
-;; under the terms of the GNU General Public License as published by the Free
-;; Software Foundation; either version 2, or (at your option) any later
-;; version.
-;;
-;; This program is distributed in the hope that it will be useful, but
-;; WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
-;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-;; for more details.
-;;
-;; You can find the GNU General Public License at
-;; http://www.gnu.org/copyleft/gpl.html
-;; or you can write to the Free Software Foundation, Inc., 59 Temple Place,
-;; Suite 330, Boston, MA 02111-1307, USA.
-
-;;; Commentary:
-
-;; This is a Q&D hack for conversion of Python manuals to on-line help format.
-;; I desperately needed usable online documenta for Python, so I wrote this.
-;; The result code is ugly and need not contain complete information from
-;; Python manuals. I apologize for my ignorance, especially ignorance to
-;; python.sty. Improvements of this convertor are welcomed.
-
-;; How to use it:
-;; Load this file and apply `M-x py2texi'. You will be asked for name of a
-;; file to be converted.
-
-;; Where to find it:
-;; New versions of this code might be found at
-;; http://www.zamazal.org/software/python/py2texi/ .
-
-;;; Code:
-
-
-(require 'texinfo)
-(eval-when-compile
- (require 'cl))
-
-
-(defvar py2texi-python-version "2.2"
- "What to substitute for the \\version macro.")
-
-(defvar py2texi-python-short-version
- (progn
- (string-match "[0-9]+\\.[0-9]+" py2texi-python-version)
- (match-string 0 py2texi-python-version))
- "Short version number, usually set by the LaTeX commands.")
-
-(defvar py2texi-texi-file-name nil
- "If non-nil, that string is used as the name of the Texinfo file.
-Otherwise a generated Texinfo file name is used.")
-
-(defvar py2texi-info-file-name nil
- "If non-nil, that string is used as the name of the Info file.
-Otherwise a generated Info file name is used.")
-
-(defvar py2texi-stop-on-problems nil
- "*If non-nil, stop when you encouter soft problem.")
-
-(defconst py2texi-environments
- '(("abstract" 0 "@quotation" "@end quotation\n")
- ("center" 0 "" "")
- ("cfuncdesc" 3
- (progn (setq findex t)
- "\n@table @code\n@item \\1 \\2(\\3)\n@findex \\2\n")
- "@end table\n")
- ("cmemberdesc" 3
- "\n@table @code\n@item \\2 \\3\n"
- "@end table\n")
- ("classdesc" 2
- (progn (setq obindex t)
- "\n@table @code\n@item \\1(\\2)\n@obindex \\1\n")
- "@end table\n")
- ("classdesc*" 1
- (progn (setq obindex t)
- "\n@table @code\n@item \\1\n@obindex \\1\n")
- "@end table\n")
- ("comment" 0 "\n@ignore\n" "\n@end ignore\n")
- ("csimplemacrodesc" 1
- (progn (setq cindex t)
- "\n@table @code\n@item \\1\n@cindex \\1\n")
- "@end table\n")
- ("ctypedesc" 1
- (progn (setq cindex t)
- "\n@table @code\n@item \\1\n@cindex \\1\n")
- "@end table\n")
- ("cvardesc" 2
- (progn (setq findex t)
- "\n@table @code\n@item \\1 \\2\n@findex \\2\n")
- "@end table\n")
- ("datadesc" 1
- (progn (setq findex t)
- "\n@table @code\n@item \\1\n@findex \\1\n")
- "@end table\n")
- ("datadescni" 1 "\n@table @code\n@item \\1\n" "@end table\n")
- ("definitions" 0 "@table @dfn" "@end table\n")
- ("description" 0 "@table @samp" "@end table\n")
- ("displaymath" 0 "" "")
- ("document" 0
- (concat "@defcodeindex mo\n"
- "@defcodeindex ob\n"
- "@titlepage\n"
- (format "@title " title "\n")
- (format "@author " author "\n")
- "@page\n"
- author-address
- "@end titlepage\n"
- "@node Top, , , (dir)\n")
- (concat "@indices\n"
- "@contents\n"
- "@bye\n"))
- ("enumerate" 0 "@enumerate" "@end enumerate")
- ("envdesc" 2 (concat "\n@table @code"
- "\n@item @backslash{}begin@{\\1@}\\2")
- "@end table\n")
- ("excdesc" 1
- (progn (setq obindex t)
- "\n@table @code\n@item \\1\n@obindex \\1\n")
- "@end table\n")
- ("excclassdesc" 2
- (progn (setq obindex t)
- "\n@table @code\n@item \\1(\\2)\n@obindex \\1\n")
- "@end table\n")
- ("flushleft" 0 "" "")
- ("fulllineitems" 0 "\n@table @code\n" "@end table\n")
- ("funcdesc" 2
- (progn (setq findex t)
- "\n@table @code\n@item \\1(\\2)\n@findex \\1\n")
- "@end table\n")
- ("funcdescni" 2 "\n@table @code\n@item \\1(\\2)\n" "@end table\n")
- ("itemize" 0 "@itemize @bullet" "@end itemize\n")
- ("list" 2 "\n@table @code\n" "@end table\n")
- ("longtableii" 4 (concat "@multitable @columnfractions .5 .5\n"
- "@item \\3 @tab \\4\n"
- "@item ------- @tab ------ \n")
- "@end multitable\n")
- ("longtableiii" 5 (concat "@multitable @columnfractions .33 .33 .33\n"
- "@item \\3 @tab \\4 @tab \\5\n"
- "@item ------- @tab ------ @tab ------\n")
- "@end multitable\n")
- ("macrodesc" 2 (concat "\n@table @code"
- "\n@item \\1@{\\2@}")
- "@end table\n")
- ("memberdesc" 1
- (progn (setq findex t)
- "\n@table @code\n@item \\1\n@findex \\1\n")
- "@end table\n")
- ("memberdescni" 1 "\n@table @code\n@item \\1\n" "@end table\n")
- ("methoddesc" 2
- (progn (setq findex t)
- "\n@table @code\n@item \\1(\\2)\n@findex \\1\n")
- "@end table\n")
- ("methoddescni" 2 "\n@table @code\n@item \\1(\\2)\n" "@end table\n")
- ("notice" 0 "@emph{Notice:} " "")
- ("opcodedesc" 2
- (progn (setq findex t)
- "\n@table @code\n@item \\1 \\2\n@findex \\1\n")
- "@end table\n")
- ("productionlist" 0 "\n@table @code\n" "@end table\n")
- ("quotation" 0 "@quotation" "@end quotation")
- ("quote" 0 "@quotation" "@end quotation")
- ("seealso" 0 "See also:\n@table @emph\n" "@end table\n")
- ("seealso*" 0 "@table @emph\n" "@end table\n")
- ("sloppypar" 0 "" "")
- ("small" 0 "" "")
- ("tableii" 4 (concat "@multitable @columnfractions .5 .5\n"
- "@item \\3 @tab \\4\n"
- "@item ------- @tab ------ \n")
- "@end multitable\n")
- ("tableiii" 5 (concat "@multitable @columnfractions .33 .33 .33\n"
- "@item \\3 @tab \\4 @tab \\5\n"
- "@item ------- @tab ------ @tab ------\n")
- "@end multitable\n")
- ("tableiv" 6 (concat
- "@multitable @columnfractions .25 .25 .25 .25\n"
- "@item \\3 @tab \\4 @tab \\5 @tab \\6\n"
- "@item ------- @tab ------- @tab ------- @tab -------\n")
- "@end multitable\n")
- ("tablev" 7 (concat
- "@multitable @columnfractions .20 .20 .20 .20 .20\n"
- "@item \\3 @tab \\4 @tab \\5 @tab \\6 @tab \\7\n"
- "@item ------- @tab ------- @tab ------- @tab ------- @tab -------\n")
- "@end multitable\n")
- ("alltt" 0 "@example" "@end example")
- )
- "Associative list defining substitutions for environments.
-Each list item is of the form (ENVIRONMENT ARGNUM BEGIN END) where:
-- ENVIRONMENT is LaTeX environment name
-- ARGNUM is number of (required) macro arguments
-- BEGIN is substitution for \begin{ENVIRONMENT}
-- END is substitution for \end{ENVIRONMENT}
-Both BEGIN and END are evaled. Moreover, you can reference arguments through
-\N regular expression notation in strings of BEGIN.")
-
-(defconst py2texi-commands
- '(("AA" 0 "@AA{}")
- ("aa" 0 "@aa{}")
- ("ABC" 0 "ABC")
- ("appendix" 0 (progn (setq appendix t) ""))
- ("ASCII" 0 "ASCII")
- ("author" 1 (progn (setq author (match-string 1 string)) ""))
- ("authoraddress" 1
- (progn (setq author-address (match-string 1 string)) ""))
- ("b" 1 "@w{\\1}")
- ("backslash" 0 "@backslash{}")
- ("bf" 0 "@destroy")
- ("bifuncindex" 1 (progn (setq findex t) "@findex{\\1}"))
- ("C" 0 "C")
- ("c" 0 "@,")
- ("catcode" 0 "")
- ("cdata" 1 "@code{\\1}")
- ("centerline" 1 "@center \\1")
- ("cfuncline" 3 "@itemx \\1 \\2(\\3)\n@findex \\2")
- ("cfunction" 1 "@code{\\1}")
- ("chapter" 1 (format "@node \\1\n@%s \\1\n"
- (if appendix "appendix" "chapter")))
- ("chapter*" 1 "@node \\1\n@unnumbered \\1\n")
- ("character" 1 "@samp{\\1}")
- ("citetitle" 1 "@ref{Top,,,\\1}")
- ("class" 1 "@code{\\1}")
- ("cmemberline" 3 "@itemx \\2 \\3\n")
- ("code" 1 "@code{\\1}")
- ("command" 1 "@command{\\1}")
- ("constant" 1 "@code{\\1}")
- ("copyright" 1 "@copyright{}")
- ("Cpp" 0 "C++")
- ("csimplemacro" 1 "@code{\\1}")
- ("ctype" 1 "@code{\\1}")
- ("dataline" 1 (progn (setq findex t) "@item \\1\n@findex \\1\n"))
- ("date" 1 "\\1")
- ("declaremodule" 2 (progn (setq cindex t) "@label{\\2}@cindex{\\2}"))
- ("deprecated" 2 "@emph{This is deprecated in Python \\1. \\2}\n\n")
- ("dfn" 1 "@dfn{\\1}")
- ("documentclass" 1 py2texi-magic)
- ("e" 0 "@backslash{}")
- ("else" 0 (concat "@end ifinfo\n@" (setq last-if "iftex")))
- ("env" 1 "@code{\\1}")
- ("EOF" 0 "@code{EOF}")
- ("email" 1 "@email{\\1}")
- ("em" 1 "@emph{\\1}")
- ("emph" 1 "@emph{\\1}")
- ("envvar" 1 "@env{\\1}")
- ("exception" 1 "@code{\\1}")
- ("exindex" 1 (progn (setq obindex t) "@obindex{\\1}"))
- ("fi" 0 (if (equal last-if "ifx") "" (concat "@end " last-if)))
- ("file" 1 "@file{\\1}")
- ("filenq" 1 "@file{\\1}")
- ("filevar" 1 "@file{@var{\\1}}")
- ("footnote" 1 "@footnote{\\1}")
- ("frac" 0 "")
- ("funcline" 2 (progn (setq findex t) "@item \\1 \\2\n@findex \\1"))
- ("funclineni" 2 "@item \\1 \\2")
- ("function" 1 "@code{\\1}")
- ("grammartoken" 1 "@code{\\1}")
- ("guilabel" 1 "@strong{\\1}")
- ("hline" 0 "")
- ("ifx" 0 (progn (setq last-if "ifx") ""))
- ("ifhtml" 0 (concat "@" (setq last-if "ifinfo")))
- ("iftexi" 0 (concat "@" (setq last-if "ifinfo")))
- ("index" 1 (progn (setq cindex t) "@cindex{\\1}"))
- ("indexii" 2 (progn (setq cindex t) "@cindex{\\1 \\2}"))
- ("indexiii" 3 (progn (setq cindex t) "@cindex{\\1 \\2 \\3}"))
- ("indexiv" 3 (progn (setq cindex t) "@cindex{\\1 \\2 \\3 \\4}"))
- ("infinity" 0 "@emph{infinity}")
- ("it" 0 "@destroy")
- ("kbd" 1 "@key{\\1}")
- ("keyword" 1 "@code{\\1}")
- ("kwindex" 1 (progn (setq cindex t) "@cindex{\\1}"))
- ("label" 1 "@label{\\1}")
- ("Large" 0 "")
- ("LaTeX" 0 "La@TeX{}")
- ("large" 0 "")
- ("ldots" 0 "@dots{}")
- ("leftline" 1 "\\1")
- ("leq" 0 "<=")
- ("lineii" 2 "@item \\1 @tab \\2")
- ("lineiii" 3 "@item \\1 @tab \\2 @tab \\3")
- ("lineiv" 4 "@item \\1 @tab \\2 @tab \\3 @tab \\4")
- ("linev" 5 "@item \\1 @tab \\2 @tab \\3 @tab \\4 @tab \\5")
- ("locallinewidth" 0 "")
- ("localmoduletable" 0 "")
- ("longprogramopt" 1 "@option{--\\1}")
- ("macro" 1 "@code{@backslash{}\\1}")
- ("mailheader" 1 "@code{\\1}")
- ("makeindex" 0 "")
- ("makemodindex" 0 "")
- ("maketitle" 0 (concat "@top " title "\n"))
- ("makevar" 1 "@code{\\1}")
- ("manpage" 2 "@samp{\\1(\\2)}")
- ("mbox" 1 "@w{\\1}")
- ("member" 1 "@code{\\1}")
- ("memberline" 1 "@item \\1\n@findex \\1\n")
- ("menuselection" 1 "@samp{\\1}")
- ("method" 1 "@code{\\1}")
- ("methodline" 2 (progn (setq moindex t) "@item \\1(\\2)\n@moindex \\1\n"))
- ("methodlineni" 2 "@item \\1(\\2)\n")
- ("mimetype" 1 "@samp{\\1}")
- ("module" 1 "@samp{\\1}")
- ("moduleauthor" 2 "")
- ("modulesynopsis" 1 "\\1")
- ("moreargs" 0 "@dots{}")
- ("n" 0 "@backslash{}n")
- ("newcommand" 2 "")
- ("newlength" 1 "")
- ("newsgroup" 1 "@samp{\\1}")
- ("nodename" 1
- (save-excursion
- (save-match-data
- (re-search-backward "^@node "))
- (delete-region (point) (save-excursion (end-of-line) (point)))
- (insert "@node " (match-string 1 string))
- ""))
- ("noindent" 0 "@noindent ")
- ("note" 1 "@emph{Note:} \\1")
- ("NULL" 0 "@code{NULL}")
- ("obindex" 1 (progn (setq obindex t) "@obindex{\\1}"))
- ("opindex" 1 (progn (setq cindex t) "@cindex{\\1}"))
- ("option" 1 "@option{\\1}")
- ("optional" 1 "[\\1]")
- ("paragraph" 1 "@subsubheading \\1")
- ("pep" 1 (progn (setq cindex t) "PEP@ \\1@cindex PEP \\1\n"))
- ("pi" 0 "pi")
- ("platform" 1 "")
- ("plusminus" 0 "+-")
- ("POSIX" 0 "POSIX")
- ("production" 2 "@item \\1 \\2")
- ("productioncont" 1 "@item @w{} \\1")
- ("program" 1 "@command{\\1}")
- ("programopt" 1 "@option{\\1}")
- ("protect" 0 "")
- ("pytype" 1 "@code{\\1}")
- ("ref" 1 "@ref{\\1}")
- ("refbimodindex" 1 (progn (setq moindex t) "@moindex{\\1}"))
- ("refmodindex" 1 (progn (setq moindex t) "@moindex{\\1}"))
- ("refmodule" 1 "@samp{\\1}")
- ("refstmodindex" 1 (progn (setq moindex t) "@moindex{\\1}"))
- ("regexp" 1 "\"\\1\"")
- ("release" 1
- (progn (setq py2texi-python-version (match-string 1 string)) ""))
- ("renewcommand" 2 "")
- ("rfc" 1 (progn (setq cindex t) "RFC@ \\1@cindex RFC \\1\n"))
- ("rm" 0 "@destroy")
- ("samp" 1 "@samp{\\1}")
- ("section" 1 (let ((str (match-string 1 string)))
- (save-match-data
- (if (string-match "\\(.*\\)[ \t\n]*---[ \t\n]*\\(.*\\)"
- str)
- (format
- "@node %s\n@section %s\n"
- (py2texi-backslash-quote (match-string 1 str))
- (py2texi-backslash-quote (match-string 2 str)))
- "@node \\1\n@section \\1\n"))))
- ("sectionauthor" 2 "")
- ("seelink" 3 "\n@table @url\n@item @strong{\\1}\n(\\2)\n\\3\n@end table\n")
- ("seemodule" 2 "@ref{\\1} \\2")
- ("seepep" 3 "\n@table @strong\n@item PEP\\1 \\2\n\\3\n@end table\n")
- ("seerfc" 3 "\n@table @strong\n@item RFC\\1 \\2\n\\3\n@end table\n")
- ("seetext" 1 "\\1")
- ("seetitle" 1 "@cite{\\1}")
- ("seeurl" 2 "\n@table @url\n@item \\1\n\\2\n@end table\n")
- ("setindexsubitem" 1 (progn (setq cindex t) "@cindex \\1"))
- ("setlength" 2 "")
- ("setreleaseinfo" 1 (progn (setq py2texi-releaseinfo "")))
- ("setshortversion" 1
- (progn (setq py2texi-python-short-version (match-string 1 string)) ""))
- ("shortversion" 0 py2texi-python-short-version)
- ("sqrt" 0 "")
- ("stindex" 1 (progn (setq cindex t) "@cindex{\\1}"))
- ("stmodindex" 1 (progn (setq moindex t) "@moindex{\\1}"))
- ("strong" 1 "@strong{\\1}")
- ("sub" 0 "/")
- ("subsection" 1 "@node \\1\n@subsection \\1\n")
- ("subsubsection" 1 "@node \\1\n@subsubsection \\1\n")
- ("sum" 0 "")
- ("tableofcontents" 0 "")
- ("term" 1 "@item \\1")
- ("TeX" 0 "@TeX{}")
- ("textasciitilde" 0 "~")
- ("textasciicircum" 0 "^")
- ("textbackslash" 0 "@backslash{}")
- ("textbar" 0 "|")
- ("textbf" 1 "@strong{\\1}")
- ("texteuro" 0 "@euro{}")
- ; Unfortunately, this alternate spelling doesn't actually apply to
- ; the usage found in Python Tutorial, which actually requires a
- ; Euro symbol to make sense, so this is commented out as well.
- ; ("texteuro" 0 "Euro ")
- ("textgreater" 0 ">")
- ("textit" 1 "@i{\\1}")
- ("textless" 0 "<")
- ("textrm" 1 "\\1")
- ("texttt" 1 "@code{\\1}")
- ("textunderscore" 0 "_")
- ("tilde" 0 "~")
- ("title" 1 (progn (setq title (match-string 1 string)) "@settitle \\1"))
- ("today" 0 "@today{}")
- ("token" 1 "@code{\\1}")
- ("tt" 0 "@destroy")
- ("ttindex" 1 (progn (setq cindex t) "@cindex{\\1}"))
- ("u" 0 "@backslash{}u")
- ("ulink" 2 "\\1")
- ("UNIX" 0 "UNIX")
- ("undefined" 0 "")
- ("unspecified" 0 "@dots{}")
- ("url" 1 "@url{\\1}")
- ("usepackage" 1 "")
- ("var" 1 "@var{\\1}")
- ("verbatiminput" 1 "@code{\\1}")
- ("version" 0 py2texi-python-version)
- ("versionadded" 1 "@emph{Added in Python version \\1}")
- ("versionchanged" 1 "@emph{Changed in Python version \\1}")
- ("vskip" 1 "")
- ("vspace" 1 "")
- ("warning" 1 "@emph{\\1}")
- ("withsubitem" 2 "\\2")
- ("XXX" 1 "@strong{\\1}"))
- "Associative list of command substitutions.
-Each list item is of the form (COMMAND ARGNUM SUBSTITUTION) where:
-- COMMAND is LaTeX command name
-- ARGNUM is number of (required) command arguments
-- SUBSTITUTION substitution for the command. It is evaled and you can
- reference command arguments through the \\N regexp notation in strings.")
-
-(defvar py2texi-magic "@documentclass\n"
- "\"Magic\" string for auxiliary insertion at the beginning of document.")
-
-(defvar py2texi-dirs '("./" "../texinputs/")
- "Where to search LaTeX input files.")
-
-(defvar py2texi-buffer "*py2texi*"
- "The name of a buffer where Texinfo is generated.")
-
-(defconst py2texi-xemacs (string-match "^XEmacs" (emacs-version))
- "Running under XEmacs?")
-
-
-(defmacro py2texi-search (regexp &rest body)
- `(progn
- (goto-char (point-min))
- (while (re-search-forward ,regexp nil t)
- ,@body)))
-
-(defmacro py2texi-search-safe (regexp &rest body)
- `(py2texi-search ,regexp
- (unless (py2texi-protected)
- ,@body)))
-
-
-(defun py2texi-message (message)
- "Report message and stop if `py2texi-stop-on-problems' is non-nil."
- (if py2texi-stop-on-problems
- (error message)
- (message message)))
-
-
-(defun py2texi-backslash-quote (string)
- "Double backslahes in STRING."
- (let ((i 0))
- (save-match-data
- (while (setq i (string-match "\\\\" string i))
- (setq string (replace-match "\\\\\\\\" t nil string))
- (setq i (+ i 2))))
- string))
-
-
-(defun py2texi (file)
- "Convert Python LaTeX documentation FILE to Texinfo."
- (interactive "fFile to convert: ")
- (switch-to-buffer (get-buffer-create py2texi-buffer))
- (erase-buffer)
- (insert-file file)
- (let ((case-fold-search nil)
- (title "")
- (author "")
- (author-address "")
- (appendix nil)
- (findex nil)
- (obindex nil)
- (cindex nil)
- (moindex nil)
- last-if)
- (py2texi-process-verbatims)
- (py2texi-process-comments)
- (py2texi-process-includes)
- (py2texi-process-funnyas)
- (py2texi-process-environments)
- (py2texi-process-commands)
- (py2texi-fix-indentation)
- (py2texi-fix-nodes)
- (py2texi-fix-references)
- (py2texi-fix-indices)
- (py2texi-process-simple-commands)
- (py2texi-fix-fonts)
- (py2texi-fix-braces)
- (py2texi-fix-backslashes)
- (py2texi-destroy-empties)
- (py2texi-fix-newlines)
- (py2texi-adjust-level))
- (let* ((texi-file-name (or py2texi-texi-file-name
- (py2texi-texi-file-name file)))
- (info-file-name (or py2texi-info-file-name
- (py2texi-info-file-name texi-file-name))))
- (goto-char (point-min))
- (when (looking-at py2texi-magic)
- (delete-region (point) (progn (beginning-of-line 2) (point)))
- (insert "\\input texinfo @c -*-texinfo-*-\n")
- (insert "@setfilename " info-file-name))
- (when (re-search-forward "@chapter" nil t)
- (texinfo-all-menus-update t))
- (goto-char (point-min))
- (write-file texi-file-name)
- (message (format "You can apply `makeinfo %s' now." texi-file-name))))
-
-
-(defun py2texi-texi-file-name (filename)
- "Generate name of Texinfo file from original file name FILENAME."
- (concat filename
- (if (string-match "\\.tex$" filename) "i" ".texi")))
-
-
-(defun py2texi-info-file-name (filename)
- "Generate name of info file from original file name FILENAME."
- (setq filename (expand-file-name filename))
- (let ((directory (file-name-directory filename))
- (basename (file-name-nondirectory filename)))
- (concat directory "python-"
- (substring basename 0 (- (length basename) 4)) "info")))
-
-
-(defun py2texi-process-verbatims ()
- "Process and protect verbatim environments."
- (let (delimiter
- beg
- end)
- (py2texi-search-safe "\\\\begin{\\(verbatim\\|displaymath\\)}"
- (when (save-excursion
- ; Make sure we aren't looking at a commented out version
- ; of a verbatim environment
- (beginning-of-line)
- (not (looking-at "%")))
- (replace-match "@example ")
- (setq beg (copy-marker (point) nil))
- (re-search-forward "\\\\end{\\(verbatim\\|displaymath\\)}")
- (setq end (copy-marker (match-beginning 0) nil))
- (replace-match "@end example")
- (py2texi-texinfo-escape beg end)
- (put-text-property (- beg (length "@example "))
- (+ end (length "@end example"))
- 'py2texi-protected t)))
- (py2texi-search-safe "\\\\verb\\([^a-z]\\)"
- (setq delimiter (match-string 1))
- (replace-match "@code{")
- (setq beg (copy-marker (point) nil))
- (re-search-forward (regexp-quote delimiter))
- (setq end (copy-marker (match-beginning 0) nil))
- (replace-match "}")
- (put-text-property (- beg (length "@code{")) (+ end (length "}"))
- 'py2texi-protected t)
- (py2texi-texinfo-escape beg end))))
-
-
-(defun py2texi-process-comments ()
- "Remove comments."
- (let (point)
- (py2texi-search-safe "%"
- (setq point (point))
- (when (save-excursion
- (re-search-backward "\\(^\\|[^\\]\\(\\\\\\\\\\)*\\)%\\=" nil t))
- (delete-region (1- point)
- (save-excursion (beginning-of-line 2) (point)))))))
-
-
-(defun py2texi-process-includes ()
- "Include LaTeX input files.
-Do not include .ind files."
- (let ((path (file-name-directory file))
- filename
- dirs
- includefile)
- (py2texi-search-safe "\\\\input{\\([^}]+\\)}"
- (setq filename (match-string 1))
- (unless (save-match-data (string-match "\\.tex$" filename))
- (setq filename (concat filename ".tex")))
- (setq includefile (save-match-data
- (string-match "\\.ind\\.tex$" filename)))
- (setq dirs py2texi-dirs)
- (while (and (not includefile) dirs)
- (setq includefile
- (concat (file-name-as-directory (car dirs)) filename))
- (if (not (file-name-absolute-p includefile))
- (setq includefile
- (concat (file-name-as-directory path) includefile)))
- (unless (file-exists-p includefile)
- (setq includefile nil)
- (setq dirs (cdr dirs))))
- (if includefile
- (save-restriction
- (narrow-to-region (match-beginning 0) (match-end 0))
- (delete-region (point-min) (point-max))
- (when (stringp includefile)
- (insert-file-contents includefile)
- (goto-char (point-min))
- (insert "\n")
- (py2texi-process-verbatims)
- (py2texi-process-comments)
- (py2texi-process-includes)))
- (replace-match (format "\\\\emph{Included file %s}" filename))
- (py2texi-message (format "Input file %s not found" filename))))))
-
-
-(defun py2texi-process-funnyas ()
- "Convert @s."
- (py2texi-search-safe "@"
- (replace-match "@@")))
-
-
-(defun py2texi-process-environments ()
- "Process LaTeX environments."
- (let ((stack ())
- kind
- environment
- parameter
- arguments
- n
- string
- description)
- (py2texi-search-safe (concat "\\\\\\(begin\\|end\\|item\\)"
- "\\({\\([^}]*\\)}\\|[[]\\([^]]*\\)[]]\\|\\)")
- (setq kind (match-string 1)
- environment (match-string 3)
- parameter (match-string 4))
- (replace-match "")
- (cond
- ((string= kind "begin")
- (setq description (assoc environment py2texi-environments))
- (if description
- (progn
- (setq n (cadr description))
- (setq description (cddr description))
- (setq string (py2texi-tex-arguments n))
- (string-match (py2texi-regexp n) string)
- ; incorrect but sufficient
- (insert (replace-match (eval (car description))
- t nil string))
- (setq stack (cons (cadr description) stack)))
- (py2texi-message (format "Unknown environment: %s" environment))
- (setq stack (cons "" stack))))
- ((string= kind "end")
- (insert (eval (car stack)))
- (setq stack (cdr stack)))
- ((string= kind "item")
- (insert "\n@item " (or parameter "") "\n"))))
- (when stack
- (py2texi-message (format "Unclosed environment: %s" (car stack))))))
-
-
-(defun py2texi-process-commands ()
- "Process LaTeX commands."
- (let (done
- command
- command-info
- string
- n)
- (while (not done)
- (setq done t)
- (py2texi-search-safe "\\\\\\([a-zA-Z*]+\\)\\(\\[[^]]*\\]\\)?"
- (setq command (match-string 1))
- (setq command-info (assoc command py2texi-commands))
- (if command-info
- (progn
- (setq done nil)
- (replace-match "")
- (setq command-info (cdr command-info))
- (setq n (car command-info))
- (setq string (py2texi-tex-arguments n))
- (string-match (py2texi-regexp n) string)
- ; incorrect but sufficient
- (insert (replace-match (eval (cadr command-info))
- t nil string)))
- (py2texi-message (format "Unknown command: %s (not processed)"
- command)))))))
-
-
-(defun py2texi-argument-pattern (count)
- (let ((filler "\\(?:[^{}]\\|\\\\{\\|\\\\}\\)*"))
- (if (<= count 0)
- filler
- (concat filler "\\(?:{"
- (py2texi-argument-pattern (1- count))
- "}" filler "\\)*" filler))))
-(defconst py2texi-tex-argument
- (concat
- "{\\("
- (py2texi-argument-pattern 10) ;really at least 10!
- "\\)}[ \t%@c\n]*")
- "Regexp describing LaTeX command argument including argument separators.")
-
-
-(defun py2texi-regexp (n)
- "Make regexp matching N LaTeX command arguments."
- (if (= n 0)
- ""
- (let ((regexp "^[^{]*"))
- (while (> n 0)
- (setq regexp (concat regexp py2texi-tex-argument))
- (setq n (1- n)))
- regexp)))
-
-
-(defun py2texi-tex-arguments (n)
- "Remove N LaTeX command arguments and return them as a string."
- (let ((point (point))
- (i 0)
- result
- match)
- (if (= n 0)
- (progn
- (when (re-search-forward "\\=\\({}\\| *\\)" nil t)
- (replace-match ""))
- "")
- (while (> n 0)
- (unless (re-search-forward
- "\\(\\=\\|[^\\\\]\\)\\(\\\\\\\\\\)*\\([{}]\\)" nil t)
- (debug))
- (if (string= (match-string 3) "{")
- (setq i (1+ i))
- (setq i (1- i))
- (when (<= i 0)
- (setq n (1- n)))))
- (setq result (buffer-substring-no-properties point (point)))
- (while (string-match "\n[ \t]*" result)
- (setq result (replace-match " " t nil result)))
- (delete-region point (point))
- result)))
-
-
-(defun py2texi-process-simple-commands ()
- "Replace single character LaTeX commands."
- (let (char)
- (py2texi-search-safe "\\\\\\([^a-z]\\)"
- (setq char (match-string 1))
- (replace-match (format "%s%s"
- (if (or (string= char "{")
- (string= char "}")
- (string= char " "))
- "@"
- "")
- (if (string= char "\\")
- "\\\\"
- char))))))
-
-
-(defun py2texi-fix-indentation ()
- "Remove white space at the beginning of lines."
- (py2texi-search-safe "^[ \t]+"
- (replace-match "")))
-
-
-(defun py2texi-fix-nodes ()
- "Remove unwanted characters from nodes and make nodes unique."
- (let ((nodes (make-hash-table :test 'equal))
- id
- counter
- string
- label
- index)
- (py2texi-search "^@node +\\(.*\\)$"
- (setq string (match-string 1))
- (if py2texi-xemacs
- (replace-match "@node " t)
- (replace-match "" t nil nil 1))
- (while (string-match "@label{[^}]*}" string)
- (setq label (match-string 0 string))
- (setq string (replace-match "" t nil string)))
- (while (string-match "@..?index{[^}]*}" string)
- (setq index (match-string 0 string))
- (setq string (replace-match "" t nil string)))
- (while (string-match "@[a-zA-Z]+\\|[{}():]\\|``\\|''" string)
- (setq string (replace-match "" t nil string)))
- (while (string-match " -- " string)
- (setq string (replace-match " - " t nil string)))
- (while (string-match "\\." string)
- (setq string (replace-match "" t nil string)))
- (when (string-match " +$" string)
- (setq string (replace-match "" t nil string)))
- (when (string-match "^\\(Built-in\\|Standard\\) Module \\|The " string)
- (setq string (replace-match "" t nil string)))
- (string-match "^[^,]+" string)
- (setq id (match-string 0 string))
- (setq counter (gethash id nodes))
- (if counter
- (progn
- (setq counter (1+ counter))
- (setq string (replace-match (format "\\& %d" counter)
- t nil string)))
- (setq counter 1))
- (setf (gethash id nodes) counter)
- (insert string)
- (beginning-of-line 3)
- (when label
- (insert label "\n"))
- (when index
- (insert index "\n")))))
-
-
-(defun py2texi-fix-references ()
- "Process labels and make references to point to appropriate nodes."
- (let ((labels ())
- node)
- (py2texi-search-safe "@label{\\([^}]*\\)}"
- (setq node (save-excursion
- (save-match-data
- (and (re-search-backward "@node +\\([^,\n]+\\)" nil t)
- (match-string 1)))))
- (when node
- (setq labels (cons (cons (match-string 1) node) labels)))
- (replace-match ""))
- (py2texi-search-safe "@ref{\\([^}]*\\)}"
- (setq node (assoc (match-string 1) labels))
- (replace-match "")
- (when node
- (insert (format "@ref{%s}" (cdr node)))))))
-
-
-(defun py2texi-fix-indices ()
- "Remove unwanted characters from @*index commands and create final indices."
- (py2texi-search-safe "@..?index\\>[^\n]*\\(\\)\n"
- (replace-match "" t nil nil 1))
- (py2texi-search-safe "@..?index\\>[^\n]*\\(\\)"
- (replace-match "\n" t nil nil 1))
- (py2texi-search-safe "@..?index\\({\\)\\([^}]+\\)\\(}+\\)"
- (replace-match " " t nil nil 1)
- (replace-match "" t nil nil 3)
- (let ((string (match-string 2)))
- (save-match-data
- (while (string-match "@[a-z]+{" string)
- (setq string (replace-match "" nil nil string)))
- (while (string-match "{" string)
- (setq string (replace-match "" nil nil string))))
- (replace-match string t t nil 2)))
- (py2texi-search-safe "@..?index\\>.*\\([{}]\\|@[a-z]*\\)"
- (replace-match "" t nil nil 1)
- (goto-char (match-beginning 0)))
- (py2texi-search-safe "[^\n]\\(\\)@..?index\\>"
- (replace-match "\n" t nil nil 1))
- (goto-char (point-max))
- (re-search-backward "@indices")
- (replace-match "")
- (insert (if moindex
- (concat "@node Module Index\n"
- "@unnumbered Module Index\n"
- "@printindex mo\n")
- "")
- (if obindex
- (concat "@node Class-Exception-Object Index\n"
- "@unnumbered Class, Exception, and Object Index\n"
- "@printindex ob\n")
- "")
- (if findex
- (concat "@node Function-Method-Variable Index\n"
- "@unnumbered Function, Method, and Variable Index\n"
- "@printindex fn\n")
- "")
- (if cindex
- (concat "@node Miscellaneous Index\n"
- "@unnumbered Miscellaneous Index\n"
- "@printindex cp\n")
- "")))
-
-
-(defun py2texi-fix-backslashes ()
- "Make backslashes from auxiliary commands."
- (py2texi-search-safe "@backslash{}"
- (replace-match "\\\\")))
-
-
-(defun py2texi-fix-fonts ()
- "Remove garbage after unstructured font commands."
- (let (string)
- (py2texi-search-safe "@destroy"
- (replace-match "")
- (when (eq (preceding-char) ?{)
- (forward-char -1)
- (setq string (py2texi-tex-arguments 1))
- (insert (substring string 1 (1- (length string))))))))
-
-
-(defun py2texi-fix-braces ()
- "Escape braces for Texinfo."
- (py2texi-search "{@{}"
- (replace-match "@{"))
- (py2texi-search "{@}}"
- (replace-match "@}"))
- (let (string)
- (py2texi-search "{"
- (unless (or (py2texi-protected)
- (save-excursion
- (re-search-backward
- "@\\([a-zA-Z]*\\|multitable.*\\){\\=" nil t)))
- (forward-char -1)
- (setq string (py2texi-tex-arguments 1))
- (insert "@" (substring string 0 (1- (length string))) "@}")))))
-
-
-(defun py2texi-fix-newlines ()
- "Remove extra newlines."
- (py2texi-search "\n\n\n+"
- (replace-match "\n\n"))
- (py2texi-search-safe "@item.*\n\n"
- (delete-backward-char 1))
- (py2texi-search "@end example"
- (unless (looking-at "\n\n")
- (insert "\n"))))
-
-
-(defun py2texi-destroy-empties ()
- "Remove all comments.
-This avoids some makeinfo errors."
- (py2texi-search "@c\\>"
- (unless (eq (py2texi-protected) t)
- (delete-region (- (point) 2) (save-excursion (end-of-line) (point)))
- (cond
- ((looking-at "\n\n")
- (delete-char 1))
- ((save-excursion (re-search-backward "^[ \t]*\\=" nil t))
- (delete-region (save-excursion (beginning-of-line) (point))
- (1+ (point))))))))
-
-
-(defun py2texi-adjust-level ()
- "Increase heading level to @chapter, if needed.
-This is only needed for distutils, so it has a very simple form only."
- (goto-char (point-min))
- (unless (re-search-forward "@chapter\\>" nil t)
- (py2texi-search-safe "@section\\>"
- (replace-match "@chapter" t))
- (py2texi-search-safe "@\\(sub\\)\\(sub\\)?section\\>"
- (replace-match "" nil nil nil 1))))
-
-
-(defun py2texi-texinfo-escape (beg end)
- "Escape Texinfo special characters in region."
- (save-excursion
- (goto-char beg)
- (while (re-search-forward "[@{}]" end t)
- (replace-match "@\\&"))))
-
-
-(defun py2texi-protected ()
- "Return protection status of the point before current point."
- (get-text-property (1- (point)) 'py2texi-protected))
-
-
-;;; Announce
-
-(provide 'py2texi)
-
-
-;;; py2texi.el ends here
diff --git a/Doc/tools/refcounts.py b/Doc/tools/refcounts.py
deleted file mode 100644
index 9efb073..0000000
--- a/Doc/tools/refcounts.py
+++ /dev/null
@@ -1,97 +0,0 @@
-"""Support functions for loading the reference count data file."""
-__version__ = '$Revision$'
-
-import os
-import sys
-
-
-# Determine the expected location of the reference count file:
-try:
- p = os.path.dirname(__file__)
-except NameError:
- p = os.path.dirname(sys.argv[0])
-p = os.path.normpath(os.path.join(os.getcwd(), p, os.pardir,
- "api", "refcounts.dat"))
-DEFAULT_PATH = p
-del p
-
-
-def load(path=DEFAULT_PATH):
- return loadfile(open(path))
-
-
-def loadfile(fp):
- d = {}
- while 1:
- line = fp.readline()
- if not line:
- break
- line = line.strip()
- if line[:1] in ("", "#"):
- # blank lines and comments
- continue
- parts = line.split(":", 4)
- if len(parts) != 5:
- raise ValueError("Not enough fields in %r" % line)
- function, type, arg, refcount, comment = parts
- if refcount == "null":
- refcount = None
- elif refcount:
- refcount = int(refcount)
- else:
- refcount = None
- #
- # Get the entry, creating it if needed:
- #
- try:
- entry = d[function]
- except KeyError:
- entry = d[function] = Entry(function)
- #
- # Update the entry with the new parameter or the result information.
- #
- if arg:
- entry.args.append((arg, type, refcount))
- else:
- entry.result_type = type
- entry.result_refs = refcount
- return d
-
-
-class Entry:
- def __init__(self, name):
- self.name = name
- self.args = []
- self.result_type = ''
- self.result_refs = None
-
-
-def dump(d):
- """Dump the data in the 'canonical' format, with functions in
- sorted order."""
- items = sorted(d.items())
- first = 1
- for k, entry in items:
- if first:
- first = 0
- else:
- print()
- s = entry.name + ":%s:%s:%s:"
- if entry.result_refs is None:
- r = ""
- else:
- r = entry.result_refs
- print(s % (entry.result_type, "", r))
- for t, n, r in entry.args:
- if r is None:
- r = ""
- print(s % (t, n, r))
-
-
-def main():
- d = load()
- dump(d)
-
-
-if __name__ == "__main__":
- main()
diff --git a/Doc/tools/rewrite.py b/Doc/tools/rewrite.py
deleted file mode 100644
index 1acdd99..0000000
--- a/Doc/tools/rewrite.py
+++ /dev/null
@@ -1,54 +0,0 @@
-"""Simple script to replace @DATE@ and friends with real information.
-
-Usage: rewrite.py boilerplate.tex [VAR=value] ... <template >output
-"""
-
-import sys
-import time
-
-
-def get_info(fp):
- s = fp.read()
-
- d = {}
- start = s.find(r"\date{")
- if start >= 0:
- end = s.find("}", start)
- date = s[start+6:end]
- if date == r"\today":
- date = time.strftime("%B %d, %Y", time.localtime(time.time()))
- d["DATE"] = date
- return d
-
-
-def main():
- s = sys.stdin.read()
- if "@" in s:
- # yes, we actully need to load the replacement values
- d = get_info(open(sys.argv[1]))
- for arg in sys.argv[2:]:
- name, value = arg.split("=", 1)
- d[name] = value
- start = 0
- while 1:
- start = s.find("@", start)
- if start < 0:
- break
- end = s.find("@", start+1)
- name = s[start+1:end]
- if name:
- value = d.get(name)
- if value is None:
- start = end + 1
- else:
- s = s[:start] + value + s[end+1:]
- start = start + len(value)
- else:
- # "@@" --> "@"
- s = s[:start] + s[end:]
- start = end
- sys.stdout.write(s)
-
-
-if __name__ == "__main__":
- main()
diff --git a/Doc/tools/sgmlconv/Makefile b/Doc/tools/sgmlconv/Makefile
deleted file mode 100644
index d222933..0000000
--- a/Doc/tools/sgmlconv/Makefile
+++ /dev/null
@@ -1,67 +0,0 @@
-# Simple makefile to control XML generation for the entire document tree.
-# This should be used from the top-level directory (Doc/), not the directory
-# that actually contains this file:
-#
-# $ pwd
-# .../Doc
-# $ make -f tools/sgmlconv/Makefile
-
-TOPDIR=.
-TOOLSDIR=tools
-
-SGMLRULES=../$(TOOLSDIR)/sgmlconv/make.rules
-# The 'inst' and 'tut' directories break the conversion, so skip them for now.
-SUBDIRS=api dist ext lib mac ref
-SUBMAKE=$(MAKE) -f $(SGMLRULES) TOOLSDIR=../$(TOOLSDIR)
-
-all: xml
-
-.PHONY: esis xml
-.PHONY: $(SUBDIRS)
-
-xml:
- for DIR in $(SUBDIRS) ; do \
- (cd $$DIR && $(SUBMAKE) xml) || exit $$? ; done
-
-esis:
- for DIR in $(SUBDIRS) ; do \
- (cd $$DIR && $(SUBMAKE) esis) || exit $$? ; done
-
-esis1:
- for DIR in $(SUBDIRS) ; do \
- (cd $$DIR && $(SUBMAKE) esis1) || exit $$? ; done
-
-tarball: xml
- tar cf - tools/sgmlconv */*.xml | gzip -9 >xml-1.5.2b2.tgz
-
-api:
- cd api && $(SUBMAKE)
-
-dist:
- cd dist && $(SUBMAKE)
-
-ext:
- cd ext && $(SUBMAKE)
-
-inst:
- cd inst && $(SUBMAKE)
-
-lib:
- cd lib && $(SUBMAKE)
-
-mac:
- cd mac && $(SUBMAKE)
-
-ref:
- cd ref && $(SUBMAKE)
-
-tut:
- cd tut && $(SUBMAKE)
-
-clean:
- for DIR in $(SUBDIRS) ; do \
- (cd $$DIR && $(SUBMAKE) clean) || exit $$? ; done
-
-clobber:
- for DIR in $(SUBDIRS) ; do \
- (cd $$DIR && $(SUBMAKE) clobber) || exit $$? ; done
diff --git a/Doc/tools/sgmlconv/README b/Doc/tools/sgmlconv/README
deleted file mode 100644
index 02564eb..0000000
--- a/Doc/tools/sgmlconv/README
+++ /dev/null
@@ -1,58 +0,0 @@
-These scripts and Makefile fragment are used to convert the Python
-documentation in LaTeX format to XML.
-
-This material is preliminary and incomplete. Python 2.0 is required.
-
-To convert all documents to XML:
-
- cd Doc/
- make -f tools/sgmlconv/Makefile
-
-To convert one document to XML:
-
- cd Doc/<document-dir>
- make -f ../tools/sgmlconv/make.rules TOOLSDIR=../tools
-
-Please send comments and bug reports to docs@python.org.
-
-
-What do the tools do?
----------------------
-
-latex2esis.py
- Reads in a conversion specification written in XML
- (conversion.xml), reads a LaTeX document fragment, and interprets
- the markup according to the specification. The output is a stream
- of ESIS events like those created by the nsgmls SGML parser, but
- is *not* guaranteed to represent a single tree! This is done to
- allow conversion per entity rather than per document. Since many
- of the LaTeX files for the Python documentation contain two
- sections on closely related modules, it is important to allow both
- of the resulting <section> elements to exist in the same output
- stream. Additionally, since comments are not supported in ESIS,
- comments are converted to <COMMENT> elements, which might exist at
- the same level as the top-level content elements.
-
- The output of latex2esis.py gets saved as <filename>.esis1.
-
-docfixer.py
- This is the really painful part of the conversion. Well, it's the
- second really painful part, but more of the pain is specific to
- the structure of the Python documentation and desired output
- rather than to the parsing of LaTeX markup.
-
- This script loads the ESIS data created by latex2esis.py into a
- DOM document *fragment* (remember, the latex2esis.py output may
- not be well-formed). Once loaded, it walks over the tree many
- times looking for a variety of possible specific
- micro-conversions. Most of the code is not in any way "general".
- After processing the fragment, a new ESIS data stream is written
- out. Like the input, it may not represent a well-formed
- document, but does represent a parsed entity.
-
- The output of docfixer.py is what gets saved in <filename>.esis.
-
-esis2sgml.py
- Reads an ESIS stream and convert to SGML or XML. This also
- converts <COMMENT> elements to real comments. This works quickly
- because there's not much to actually do.
diff --git a/Doc/tools/sgmlconv/conversion.xml b/Doc/tools/sgmlconv/conversion.xml
deleted file mode 100644
index f0151f4..0000000
--- a/Doc/tools/sgmlconv/conversion.xml
+++ /dev/null
@@ -1,914 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<conversion>
- <!-- Miscellaneous. -->
- <macro name="declaremodule">
- <attribute name="id" optional="yes"/>
- <attribute name="type"/>
- <attribute name="name"/>
- </macro>
- <macro name="modulesynopsis">
- <content/>
- </macro>
- <macro name="platform">
- <content/>
- </macro>
- <macro name="deprecated">
- <attribute name="version"/>
- <content/>
- </macro>
- <macro name="label">
- <attribute name="id"/>
- </macro>
- <macro name="nodename" outputname="label">
- <attribute name="id"/>
- </macro>
- <macro name="localmoduletable"/>
- <macro name="manpage">
- <attribute name="name"/>
- <attribute name="section"/>
- </macro>
- <macro name="module">
- <content/>
- </macro>
- <macro name="moduleauthor">
- <attribute name="name"/>
- <attribute name="email"/>
- </macro>
- <macro name="citetitle">
- <attribute name="href" optional="yes"/>
- <content/>
- </macro>
- <macro name="pep">
- <attribute name="num"/>
- </macro>
- <macro name="rfc">
- <attribute name="num"/>
- </macro>
- <macro name="sectionauthor" outputname="author">
- <attribute name="name"/>
- <attribute name="email"/>
- </macro>
- <macro name="author">
- <attribute name="name"/>
- </macro>
- <macro name="authoraddress">
- <content/>
- </macro>
- <macro name="shortversion"/>
- <macro name="note">
- <content/>
- </macro>
- <macro name="warning">
- <content/>
- </macro>
- <environment name="notice">
- <attribute name="role" optional="yes"/>
- </environment>
-
- <macro name="menuselection">
- <content/>
- </macro>
- <macro name="sub"/>
-
- <!-- These are broken: we need to re-order the optional and required
- parameters, making the optional parameter the content for the
- element. latex2esis.py is not powerful enough to handle this.
- -->
- <macro name="versionadded">
- <attribute name="info" optional="yes"/>
- <attribute name="version"/>
- </macro>
- <macro name="versionchanged">
- <attribute name="info" optional="yes"/>
- <attribute name="version"/>
- </macro>
-
- <!-- Module referencing. -->
- <macro name="refmodule" outputname="module">
- <!-- this causes the optional parameter to \refmodule to be
- discarded -->
- <attribute name="" optional="yes"/>
- <content/>
- </macro>
-
- <!-- Information units. -->
- <!-- C things. -->
- <environment name="cfuncdesc">
- <attribute name="type"/>
- <attribute name="name"/>
- <child name="args"/>
- </environment>
- <environment name="csimplemacrodesc">
- <attribute name="name"/>
- </environment>
- <environment name="ctypedesc">
- <attribute name="tag" optional="yes"/>
- <attribute name="name"/>
- </environment>
- <environment name="cvardesc">
- <attribute name="type"/>
- <attribute name="name"/>
- </environment>
-
- <!-- Python things. -->
- <macro name="optional">
- <content/>
- </macro>
- <macro name="unspecified"/>
- <macro name="moreargs"/>
- <environment name="classdesc">
- <attribute name="name"/>
- <child name="args"/>
- </environment>
- <environment name="classdesc*" outputname="classdesc">
- <attribute name="name"/>
- </environment>
- <environment name="datadesc">
- <attribute name="name"/>
- </environment>
- <environment name="datadescni" outputname="datadesc">
- <attribute name="index">no</attribute>
- <attribute name="name"/>
- </environment>
- <macro name="dataline">
- <attribute name="name"/>
- </macro>
- <environment name="excclassdesc">
- <attribute name="name"/>
- <child name="args"/>
- </environment>
- <environment name="excdesc">
- <attribute name="name"/>
- </environment>
-
- <environment name="funcdesc">
- <attribute name="name"/>
- <child name="args"/>
- </environment>
- <macro name="funcline">
- <attribute name="name"/>
- <child name="args"/>
- </macro>
- <environment name="funcdescni" outputname="funcdesc">
- <attribute name="index">no</attribute>
- <attribute name="name"/>
- <child name="args"/>
- </environment>
- <macro name="funclineni" outputname="funcline">
- <attribute name="index">no</attribute>
- <attribute name="name"/>
- <child name="args"/>
- </macro>
-
- <environment name="memberdesc">
- <attribute name="class" optional="yes"/>
- <attribute name="name"/>
- </environment>
- <environment name="memberdescni" outputname="memberdesc">
- <attribute name="index">no</attribute>
- <attribute name="class" optional="yes"/>
- <attribute name="name"/>
- </environment>
- <macro name="memberline">
- <attribute name="name"/>
- </macro>
-
- <environment name="methoddesc">
- <attribute name="class" optional="yes"/>
- <attribute name="name"/>
- <child name="args"/>
- </environment>
- <macro name="methodline">
- <attribute name="class" optional="yes"/>
- <attribute name="name"/>
- <child name="args"/>
- </macro>
- <environment name="methoddescni">
- <attribute name="index">no</attribute>
- <attribute name="class" optional="yes"/>
- <attribute name="name"/>
- <child name="args"/>
- </environment>
- <macro name="methodlineni" outputname="methodline">
- <attribute name="index">no</attribute>
- <attribute name="class" optional="yes"/>
- <attribute name="name"/>
- <child name="args"/>
- </macro>
-
- <environment name="opcodedesc">
- <attribute name="name"/>
- <attribute name="var"/>
- </environment>
-
- <!-- "See also:" sections. -->
- <environment name="seealso*" outputname="seealso">
- <attribute name="sidebar">no</attribute>
- </environment>
- <macro name="seemodule">
- <!-- this causes the optional parameter to \seemodule to be
- discarded -->
- <attribute name="" optional="yes"/>
- <attribute name="name"/>
- <child name="description"/>
- </macro>
- <macro name="seepep">
- <attribute name="number"/>
- <child name="title"/>
- <child name="description"/>
- </macro>
- <macro name="seerfc">
- <attribute name="number"/>
- <child name="title"/>
- <child name="description"/>
- </macro>
- <macro name="seetext">
- <child name="description"/>
- </macro>
- <macro name="seetitle">
- <attribute name="href" optional="yes"/>
- <child name="title"/>
- <child name="description"/>
- </macro>
- <macro name="seeurl">
- <attribute name="href"/>
- <child name="description"/>
- </macro>
-
- <!-- Index-generating markup. -->
- <macro name="index" outputname="indexterm">
- <attribute name="term1"/>
- </macro>
- <macro name="indexii" outputname="indexterm">
- <attribute name="term1"/>
- <attribute name="term2"/>
- </macro>
- <macro name="indexiii" outputname="indexterm">
- <attribute name="term1"/>
- <attribute name="term2"/>
- <attribute name="term3"/>
- </macro>
- <macro name="indexiv" outputname="indexterm">
- <attribute name="term1"/>
- <attribute name="term2"/>
- <attribute name="term3"/>
- <attribute name="term4"/>
- </macro>
-
- <macro name="ttindex" outputname="indexterm">
- <attribute name="style">tt</attribute>
- <attribute name="term1"/>
- </macro>
-
- <macro name="refmodindex">
- <attribute name="module"/>
- </macro>
- <macro name="stmodindex">
- <attribute name="module"/>
- </macro>
- <macro name="refbimodindex" outputname="refmodindex">
- <attribute name="module"/>
- </macro>
- <macro name="refexmodindex" outputname="refmodindex">
- <attribute name="module"/>
- </macro>
- <macro name="refstmodindex" outputname="refmodindex">
- <attribute name="module"/>
- </macro>
-
- <macro name="bifuncindex">
- <attribute name="name"/>
- </macro>
- <macro name="exindex">
- <attribute name="name"/>
- </macro>
- <macro name="obindex">
- <attribute name="name"/>
- </macro>
- <macro name="kwindex">
- <attribute name="name"/>
- </macro>
- <macro name="opindex">
- <attribute name="type"/>
- </macro>
- <macro name="stindex">
- <attribute name="type"/>
- </macro>
- <macro name="withsubitem">
- <attribute name="text"/>
- <content/>
- </macro>
- <macro name="setindexsubitem">
- <attribute name="text"/>
- </macro>
-
- <!-- Entity management. -->
- <macro name="include" outputname="xi:include">
- <attribute name="href"/>
- </macro>
- <macro name="input" outputname="xi:include">
- <attribute name="href"/>
- </macro>
-
- <!-- Large-scale document structure. -->
- <macro name="documentclass">
- <attribute name="classname"/>
- </macro>
-
- <macro name="usepackage">
- <attribute name="options" optional="yes"/>
- <attribute name="pkg"/>
- </macro>
-
- <environment name="document"
- endcloses="chapter chapter* section section*
- subsection subsection*
- subsubsection subsubsection*
- paragraph paragraph* subparagraph
- subparagraph*">
- <attribute name="xmlns:xi"
- >http://www.w3.org/2001/XInclude</attribute>
- </environment>
-
- <macro name="chapter"
- closes="chapter chapter* section section* subsection subsection*
- subsubsection subsubsection*
- paragraph paragraph* subparagraph subparagraph*">
- <text>
-</text>
- <child name="title"/>
- <content implied="yes"/>
- </macro>
- <macro name="chapter*" outputname="chapter"
- closes="chapter chapter* section section* subsection subsection*
- subsubsection subsubsection*
- paragraph paragraph* subparagraph subparagraph*">
- <attribute name="numbered">no</attribute>
- <text>
-</text>
- <child name="title"/>
- <content implied="yes"/>
- </macro>
-
- <macro name="section"
- closes="section section* subsection subsection*
- subsubsection subsubsection*
- paragraph paragraph* subparagraph subparagraph*">
- <text>
-</text>
- <child name="title"/>
- <content implied="yes"/>
- </macro>
- <macro name="section*" outputname="section"
- closes="section section* subsection subsection*
- subsubsection subsubsection*
- paragraph paragraph* subparagraph subparagraph*">
- <attribute name="numbered">no</attribute>
- <text>
-</text>
- <child name="title"/>
- <content implied="yes"/>
- </macro>
-
- <macro name="subsection"
- closes="subsection subsection* subsubsection subsubsection*
- paragraph paragraph* subparagraph subparagraph*">
- <text>
-</text>
- <child name="title"/>
- <content implied="yes"/>
- </macro>
- <macro name="subsection*" outputname="subsection"
- closes="subsection subsection* subsubsection subsubsection*
- paragraph paragraph* subparagraph subparagraph*">
- <attribute name="numbered">no</attribute>
- <text>
-</text>
- <child name="title"/>
- <content implied="yes"/>
- </macro>
-
- <macro name="subsubsection"
- closes="subsubsection subsubsection*
- paragraph paragraph* subparagraph subparagraph*">
- <text>
-</text>
- <child name="title"/>
- <content implied="yes"/>
- </macro>
- <macro name="subsubsection*" outputname="subsubsection"
- closes="subsubsection subsubsection*
- paragraph paragraph* subparagraph subparagraph*">
- <attribute name="numbered">no</attribute>
- <text>
-</text>
- <child name="title"/>
- <content implied="yes"/>
- </macro>
-
- <macro name="paragraph"
- closes="paragraph paragraph* subparagraph subparagraph*">
- <text>
-</text>
- <child name="title"/>
- <content implied="yes"/>
- </macro>
- <macro name="paragraph*" outputname="paragraph"
- closes="paragraph paragraph* subparagraph subparagraph*">
- <attribute name="numbered">no</attribute>
- <text>
-</text>
- <child name="title"/>
- <content implied="yes"/>
- </macro>
-
- <macro name="subparagraph"
- closes="subparagraph subparagraph*">
- <text>
-</text>
- <child name="title"/>
- <content implied="yes"/>
- </macro>
- <macro name="subparagraph*" outputname="subparagraph"
- closes="subparagraph subparagraph*">
- <attribute name="numbered">no</attribute>
- <text>
-</text>
- <child name="title"/>
- <content implied="yes"/>
- </macro>
- <macro name="title">
- <content/>
- </macro>
-
- <macro name="appendix" outputname="back-matter"
- closes="chapter chapter* section subsection subsubsection
- paragraph subparagraph"/>
-
- <environment name="list"
- endcloses="item">
- <attribute name="bullet"/>
- <attribute name="init"/>
- </environment>
- <macro name="item" closes="item">
- <child name="leader" optional="yes"/>
- <content implied="yes"/>
- </macro>
-
- <macro name="ref">
- <attribute name="ref"/>
- </macro>
-
- <environment name="description" outputname="descriptionlist"
- endcloses="item"/>
-
- <environment name="enumerate" outputname="enumeration"
- endcloses="item"/>
-
- <environment name="fulllineitems"
- endcloses="item"/>
-
- <environment name="itemize"
- endcloses="item"/>
-
- <environment name="definitions" outputname="definitionlist"
- encloses="term"/>
- <macro name="term" closes="definition">
- <!-- not really optional, but uses the [] syntax -->
- <child name="term" optional="yes"/>
- <child name="definition" implied="yes"/>
- </macro>
-
- <environment name="alltt" outputname="verbatim"/>
- <environment name="comment" verbatim="yes"/>
- <environment name="verbatim" verbatim="yes"/>
- <environment name="verbatim*" verbatim="yes">
- <!-- not used anywhere, but it's a standard LaTeXism -->
- <attribute name="spaces">visible</attribute>
- </environment>
- <macro name="verbatiminput" ouptutname="xi:include">
- <attribute name="parse">text</attribute>
- <attribute name="href"/>
- </macro>
-
- <!-- Table markup. -->
- <macro name="hline"/>
- <environment name="tableii" outputname="table">
- <attribute name="cols">2</attribute>
- <attribute name="colspec"/>
- <attribute name="style"/>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- </environment>
- <environment name="longtableii" outputname="table">
- <attribute name="cols">2</attribute>
- <attribute name="colspec"/>
- <attribute name="style"/>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- </environment>
- <macro name="lineii" outputname="row">
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- </macro>
-
- <environment name="tableiii" outputname="table">
- <attribute name="cols">3</attribute>
- <attribute name="colspec"/>
- <attribute name="style"/>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- </environment>
- <environment name="longtableiii" outputname="table">
- <attribute name="cols">3</attribute>
- <attribute name="colspec"/>
- <attribute name="style"/>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- </environment>
- <macro name="lineiii" outputname="row">
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- </macro>
-
- <environment name="tableiv" outputname="table">
- <attribute name="cols">4</attribute>
- <attribute name="colspec"/>
- <attribute name="style"/>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- </environment>
- <environment name="longtableiv" outputname="table">
- <attribute name="cols">4</attribute>
- <attribute name="colspec"/>
- <attribute name="style"/>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- </environment>
- <macro name="lineiv" outputname="row">
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- </macro>
-
- <environment name="tablev" outputname="table">
- <attribute name="cols">4</attribute>
- <attribute name="colspec"/>
- <attribute name="style"/>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- </environment>
- <environment name="longtablev" outputname="table">
- <attribute name="cols">4</attribute>
- <attribute name="colspec"/>
- <attribute name="style"/>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- </environment>
- <macro name="linev" outputname="row">
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- <text>
- </text>
- <child name="entry"/>
- </macro>
-
- <!-- These are handled at a later translation stage, at least for now. -->
- <macro name="Cpp" outputname="">
- <text>C++</text>
- </macro>
- <macro name="geq" outputname="">
- <entityref name="geq"/>
- </macro>
- <macro name="infinity" outputname="">
- <entityref name="infin"/>
- </macro>
- <macro name="LaTeX" outputname="">
- <text>LaTeX</text>
- </macro>
- <macro name="ldots" outputname="">
- <text>...</text>
- </macro>
- <macro name="leq" outputname="">
- <entityref name="leq"/>
- </macro>
- <macro name="plusminus" outputname="">
- <entityref name="plusmn"/>
- </macro>
- <macro name="TeX" outputname="">
- <text>TeX</text>
- </macro>
- <macro name="version"/>
-
- <!-- Distutils things. -->
- <macro name="command">
- <content/>
- </macro>
- <macro name="option">
- <content/>
- </macro>
- <macro name="filevar" outputname="var">
- <content/>
- </macro>
- <macro name="XXX" outputname="editorial-comment">
- <content/>
- </macro>
-
- <!-- Grammar production lists -->
- <environment name="productionlist">
- <attribute name="grammar" optional="yes"/>
- </environment>
- <macro name="production">
- <attribute name="token"/>
- <content/>
- </macro>
- <macro name="productioncont">
- <content/>
- </macro>
- <macro name="token" outputname="grammartoken">
- <content/>
- </macro>
- <macro name="grammartoken">
- <content/>
- </macro>
-
- <!-- Misc. -->
- <macro name="emph">
- <content/>
- </macro>
- <macro name="strong">
- <content/>
- </macro>
- <macro name="textrm">
- <content/>
- </macro>
- <macro name="texttt">
- <content/>
- </macro>
- <macro name="code">
- <content/>
- </macro>
- <macro name="exception">
- <content/>
- </macro>
- <macro name="keyword">
- <content/>
- </macro>
- <macro name="samp">
- <content/>
- </macro>
- <macro name="class">
- <content/>
- </macro>
- <macro name="cdata">
- <content/>
- </macro>
- <macro name="cfunction">
- <content/>
- </macro>
- <macro name="csimplemacro">
- <content/>
- </macro>
- <macro name="ctype">
- <content/>
- </macro>
- <macro name="pytype">
- <content/>
- </macro>
- <macro name="character">
- <content/>
- </macro>
- <macro name="constant">
- <content/>
- </macro>
- <macro name="envvar" outputname="envar">
- <content/>
- </macro>
- <macro name="file" outputname="filename">
- <content/>
- </macro>
- <macro name="filenq" outputname="filename">
- <attribute name="quote">no</attribute>
- <content/>
- </macro>
- <macro name="function">
- <content/>
- </macro>
- <macro name="kbd" outputname="keysym">
- <content/>
- </macro>
- <macro name="mailheader">
- <content/>
- </macro>
- <macro name="makevar">
- <content/>
- </macro>
- <macro name="method">
- <content/>
- </macro>
- <macro name="member">
- <content/>
- </macro>
- <macro name="mimetype">
- <content/>
- </macro>
- <macro name="newsgroup">
- <content/>
- </macro>
- <macro name="program" outputname="command">
- <content/>
- </macro>
- <macro name="programopt" outputname="option">
- <content/>
- </macro>
- <macro name="longprogramopt" outputname="longoption">
- <content/>
- </macro>
- <macro name="regexp">
- <content/>
- </macro>
- <macro name="var">
- <content/>
- </macro>
- <macro name="email">
- <content/>
- </macro>
- <macro name="ulink">
- <!-- order of the parameters makes this difficult;
- we'll need to fix it up to <ulink href="...">...</ulink>
- in docfixer.py.
- -->
- <child name="text"/>
- <child name="href"/>
- </macro>
- <macro name="url">
- <content/>
- </macro>
- <macro name="footnote">
- <content/>
- </macro>
- <macro name="dfn" outputname="definedterm">
- <content/>
- </macro>
-
- <macro name="mbox">
- <content/>
- </macro>
-
- <!-- minimal math stuff to get by -->
- <macro name="pi"/>
- <macro name="sqrt">
- <content/>
- </macro>
- <macro name="frac" outputname="fraction">
- <child name="numerator"/>
- <child name="denominator"/>
- </macro>
- <macro name="sum">
- <content/>
- </macro>
-
- <macro name="leftline" outputname="">
- <content/>
- </macro>
-
- <!-- Conversions to text; perhaps could be different? There's -->
- <!-- no way for a style sheet to work with these this way. -->
- <macro name="ABC" outputname="">
- <text>ABC</text>
- </macro>
- <macro name="ASCII" outputname="">
- <text>ASCII</text>
- </macro>
- <macro name="C" outputname="">
- <text>C</text>
- </macro>
- <macro name="EOF" outputname="">
- <text>EOF</text>
- </macro>
- <macro name="e" outputname="">
- <text>\</text>
- </macro>
- <macro name="NULL" outputname="constant">
- <text>NULL</text>
- </macro>
- <macro name="POSIX" outputname="">
- <text>POSIX</text>
- </macro>
- <macro name="UNIX" outputname="">
- <text>Unix</text>
- </macro>
- <macro name="textasciicircum" outputname="">
- <text>^</text>
- </macro>
- <macro name="textasciitilde" outputname="">
- <text>~</text>
- </macro>
- <macro name="textbackslash" outputname="">
- <text>\</text>
- </macro>
- <macro name="textbar" outputname="">
- <text>|</text>
- </macro>
- <macro name="textgreater" outputname="">
- <text>&gt;</text>
- </macro>
- <macro name="textless" outputname="">
- <text>&lt;</text>
- </macro>
-
- <!-- These will end up disappearing as well! -->
- <macro name="catcode" outputname=""/>
- <macro name="fi" outputname=""/>
- <macro name="ifhtml" outputname=""/>
- <macro name="indexname" outputname=""/>
- <macro name="labelwidth" outputname=""/>
- <macro name="large" outputname=""/>
- <macro name="leftmargin" outputname=""/>
- <macro name="makeindex" outputname=""/>
- <macro name="makemodindex" outputname=""/>
- <macro name="maketitle" outputname=""/>
- <macro name="noindent" outputname=""/>
- <macro name="protect" outputname=""/>
- <macro name="textwidth"/>
- <macro name="renewcommand">
- <attribute name="macro"/>
- <attribute name="nargs" optional="yes"/>
- <content/>
- </macro>
- <macro name="tableofcontents" outputname=""/>
- <macro name="vspace">
- <attribute name="size"/>
- </macro>
-</conversion>
diff --git a/Doc/tools/sgmlconv/docfixer.py b/Doc/tools/sgmlconv/docfixer.py
deleted file mode 100755
index 8459fa2..0000000
--- a/Doc/tools/sgmlconv/docfixer.py
+++ /dev/null
@@ -1,1072 +0,0 @@
-#! /usr/bin/env python
-
-"""Perform massive transformations on a document tree created from the LaTeX
-of the Python documentation, and dump the ESIS data for the transformed tree.
-"""
-
-
-import errno
-import esistools
-import re
-import sys
-import xml.dom
-import xml.dom.minidom
-
-ELEMENT = xml.dom.Node.ELEMENT_NODE
-ENTITY_REFERENCE = xml.dom.Node.ENTITY_REFERENCE_NODE
-TEXT = xml.dom.Node.TEXT_NODE
-
-
-class ConversionError(Exception):
- pass
-
-
-ewrite = sys.stderr.write
-try:
- # We can only do this trick on Unix (if tput is on $PATH)!
- if sys.platform != "posix" or not sys.stderr.isatty():
- raise ImportError
- import commands
-except ImportError:
- bwrite = ewrite
-else:
- def bwrite(s, BOLDON=commands.getoutput("tput bold"),
- BOLDOFF=commands.getoutput("tput sgr0")):
- ewrite("%s%s%s" % (BOLDON, s, BOLDOFF))
-
-
-PARA_ELEMENT = "para"
-
-DEBUG_PARA_FIXER = 0
-
-if DEBUG_PARA_FIXER:
- def para_msg(s):
- ewrite("*** %s\n" % s)
-else:
- def para_msg(s):
- pass
-
-
-def get_first_element(doc, gi):
- for n in doc.childNodes:
- if n.nodeName == gi:
- return n
-
-def extract_first_element(doc, gi):
- node = get_first_element(doc, gi)
- if node is not None:
- doc.removeChild(node)
- return node
-
-
-def get_documentElement(node):
- result = None
- for child in node.childNodes:
- if child.nodeType == ELEMENT:
- result = child
- return result
-
-
-def set_tagName(elem, gi):
- elem.nodeName = elem.tagName = gi
-
-
-def find_all_elements(doc, gi):
- nodes = []
- if doc.nodeName == gi:
- nodes.append(doc)
- for child in doc.childNodes:
- if child.nodeType == ELEMENT:
- if child.tagName == gi:
- nodes.append(child)
- for node in child.getElementsByTagName(gi):
- nodes.append(node)
- return nodes
-
-def find_all_child_elements(doc, gi):
- nodes = []
- for child in doc.childNodes:
- if child.nodeName == gi:
- nodes.append(child)
- return nodes
-
-
-def find_all_elements_from_set(doc, gi_set):
- return __find_all_elements_from_set(doc, gi_set, [])
-
-def __find_all_elements_from_set(doc, gi_set, nodes):
- if doc.nodeName in gi_set:
- nodes.append(doc)
- for child in doc.childNodes:
- if child.nodeType == ELEMENT:
- __find_all_elements_from_set(child, gi_set, nodes)
- return nodes
-
-
-def simplify(doc, fragment):
- # Try to rationalize the document a bit, since these things are simply
- # not valid SGML/XML documents as they stand, and need a little work.
- documentclass = "document"
- inputs = []
- node = extract_first_element(fragment, "documentclass")
- if node is not None:
- documentclass = node.getAttribute("classname")
- node = extract_first_element(fragment, "title")
- if node is not None:
- inputs.append(node)
- # update the name of the root element
- node = get_first_element(fragment, "document")
- if node is not None:
- set_tagName(node, documentclass)
- # Move everything that comes before this node into this node;
- # this will be the document element.
- nodelist = fragment.childNodes
- point = node.firstChild
- while not nodelist[0].isSameNode(node):
- node.insertBefore(nodelist[0], point)
- while 1:
- node = extract_first_element(fragment, "input")
- if node is None:
- break
- inputs.append(node)
- if inputs:
- docelem = get_documentElement(fragment)
- inputs.reverse()
- for node in inputs:
- text = doc.createTextNode("\n")
- docelem.insertBefore(text, docelem.firstChild)
- docelem.insertBefore(node, text)
- docelem.insertBefore(doc.createTextNode("\n"), docelem.firstChild)
- while fragment.firstChild and fragment.firstChild.nodeType == TEXT:
- fragment.removeChild(fragment.firstChild)
-
-
-def cleanup_root_text(doc):
- discards = []
- skip = 0
- for n in doc.childNodes:
- prevskip = skip
- skip = 0
- if n.nodeType == TEXT and not prevskip:
- discards.append(n)
- elif n.nodeName == "COMMENT":
- skip = 1
- for node in discards:
- doc.removeChild(node)
-
-
-DESCRIPTOR_ELEMENTS = (
- "cfuncdesc", "cvardesc", "ctypedesc",
- "classdesc", "memberdesc", "memberdescni", "methoddesc", "methoddescni",
- "excdesc", "funcdesc", "funcdescni", "opcodedesc",
- "datadesc", "datadescni",
- )
-
-def fixup_descriptors(doc, fragment):
- sections = find_all_elements(fragment, "section")
- for section in sections:
- find_and_fix_descriptors(doc, section)
-
-
-def find_and_fix_descriptors(doc, container):
- children = container.childNodes
- for child in children:
- if child.nodeType == ELEMENT:
- tagName = child.tagName
- if tagName in DESCRIPTOR_ELEMENTS:
- rewrite_descriptor(doc, child)
- elif tagName == "subsection":
- find_and_fix_descriptors(doc, child)
-
-
-def rewrite_descriptor(doc, descriptor):
- #
- # Do these things:
- # 1. Add an "index='no'" attribute to the element if the tagName
- # ends in 'ni', removing the 'ni' from the name.
- # 2. Create a <signature> from the name attribute
- # 2a.Create an <args> if it appears to be available.
- # 3. Create additional <signature>s from <*line{,ni}> elements,
- # if found.
- # 4. If a <versionadded> is found, move it to an attribute on the
- # descriptor.
- # 5. Move remaining child nodes to a <description> element.
- # 6. Put it back together.
- #
- # 1.
- descname = descriptor.tagName
- index = descriptor.getAttribute("name") != "no"
- desctype = descname[:-4] # remove 'desc'
- linename = desctype + "line"
- if not index:
- linename = linename + "ni"
- # 2.
- signature = doc.createElement("signature")
- name = doc.createElement("name")
- signature.appendChild(doc.createTextNode("\n "))
- signature.appendChild(name)
- name.appendChild(doc.createTextNode(descriptor.getAttribute("name")))
- descriptor.removeAttribute("name")
- # 2a.
- if descriptor.hasAttribute("var"):
- if descname != "opcodedesc":
- raise RuntimeError("got 'var' attribute on descriptor other than opcodedesc")
- variable = descriptor.getAttribute("var")
- if variable:
- args = doc.createElement("args")
- args.appendChild(doc.createTextNode(variable))
- signature.appendChild(doc.createTextNode("\n "))
- signature.appendChild(args)
- descriptor.removeAttribute("var")
- newchildren = [signature]
- children = descriptor.childNodes
- pos = skip_leading_nodes(children)
- if pos < len(children):
- child = children[pos]
- if child.nodeName == "args":
- # move <args> to <signature>, or remove if empty:
- child.parentNode.removeChild(child)
- if len(child.childNodes):
- signature.appendChild(doc.createTextNode("\n "))
- signature.appendChild(child)
- signature.appendChild(doc.createTextNode("\n "))
- # 3, 4.
- pos = skip_leading_nodes(children, pos)
- while pos < len(children) \
- and children[pos].nodeName in (linename, "versionadded"):
- if children[pos].tagName == linename:
- # this is really a supplemental signature, create <signature>
- oldchild = children[pos].cloneNode(1)
- try:
- sig = methodline_to_signature(doc, children[pos])
- except KeyError:
- print(oldchild.toxml())
- raise
- newchildren.append(sig)
- else:
- # <versionadded added=...>
- descriptor.setAttribute(
- "added", children[pos].getAttribute("version"))
- pos = skip_leading_nodes(children, pos + 1)
- # 5.
- description = doc.createElement("description")
- description.appendChild(doc.createTextNode("\n"))
- newchildren.append(description)
- move_children(descriptor, description, pos)
- last = description.childNodes[-1]
- if last.nodeType == TEXT:
- last.data = last.data.rstrip() + "\n "
- # 6.
- # should have nothing but whitespace and signature lines in <descriptor>;
- # discard them
- while descriptor.childNodes:
- descriptor.removeChild(descriptor.childNodes[0])
- for node in newchildren:
- descriptor.appendChild(doc.createTextNode("\n "))
- descriptor.appendChild(node)
- descriptor.appendChild(doc.createTextNode("\n"))
-
-
-def methodline_to_signature(doc, methodline):
- signature = doc.createElement("signature")
- signature.appendChild(doc.createTextNode("\n "))
- name = doc.createElement("name")
- name.appendChild(doc.createTextNode(methodline.getAttribute("name")))
- methodline.removeAttribute("name")
- signature.appendChild(name)
- if len(methodline.childNodes):
- args = doc.createElement("args")
- signature.appendChild(doc.createTextNode("\n "))
- signature.appendChild(args)
- move_children(methodline, args)
- signature.appendChild(doc.createTextNode("\n "))
- return signature
-
-
-def move_children(origin, dest, start=0):
- children = origin.childNodes
- while start < len(children):
- node = children[start]
- origin.removeChild(node)
- dest.appendChild(node)
-
-
-def handle_appendix(doc, fragment):
- # must be called after simplfy() if document is multi-rooted to begin with
- docelem = get_documentElement(fragment)
- toplevel = docelem.tagName == "manual" and "chapter" or "section"
- appendices = 0
- nodes = []
- for node in docelem.childNodes:
- if appendices:
- nodes.append(node)
- elif node.nodeType == ELEMENT:
- appnodes = node.getElementsByTagName("appendix")
- if appnodes:
- appendices = 1
- parent = appnodes[0].parentNode
- parent.removeChild(appnodes[0])
- parent.normalize()
- if nodes:
- map(docelem.removeChild, nodes)
- docelem.appendChild(doc.createTextNode("\n\n\n"))
- back = doc.createElement("back-matter")
- docelem.appendChild(back)
- back.appendChild(doc.createTextNode("\n"))
- while nodes and nodes[0].nodeType == TEXT \
- and not nodes[0].data.strip():
- del nodes[0]
- map(back.appendChild, nodes)
- docelem.appendChild(doc.createTextNode("\n"))
-
-
-def handle_labels(doc, fragment):
- for label in find_all_elements(fragment, "label"):
- id = label.getAttribute("id")
- if not id:
- continue
- parent = label.parentNode
- parentTagName = parent.tagName
- if parentTagName == "title":
- parent.parentNode.setAttribute("id", id)
- else:
- parent.setAttribute("id", id)
- # now, remove <label id="..."/> from parent:
- parent.removeChild(label)
- if parentTagName == "title":
- parent.normalize()
- children = parent.childNodes
- if children[-1].nodeType == TEXT:
- children[-1].data = children[-1].data.rstrip()
-
-
-def fixup_trailing_whitespace(doc, fragment, wsmap):
- queue = [fragment]
- fixups = []
- while queue:
- node = queue[0]
- del queue[0]
- if node.nodeName in wsmap:
- fixups.append(node)
- for child in node.childNodes:
- if child.nodeType == ELEMENT:
- queue.append(child)
-
- # reverse the list to process from the inside out
- fixups.reverse()
- for node in fixups:
- node.parentNode.normalize()
- lastchild = node.lastChild
- before, after = wsmap[node.tagName]
- if lastchild.nodeType == TEXT:
- data = lastchild.data.rstrip() + before
- lastchild.data = data
- norm = 0
- if wsmap[node.tagName]:
- nextnode = node.nextSibling
- if nextnode and nextnode.nodeType == TEXT:
- nextnode.data = after + nextnode.data.lstrip()
- else:
- wsnode = doc.createTextNode(after)
- node.parentNode.insertBefore(wsnode, nextnode)
- # hack to get the title in place:
- if node.tagName == "title" \
- and node.parentNode.firstChild.nodeType == ELEMENT:
- node.parentNode.insertBefore(doc.createTextNode("\n "),
- node.parentNode.firstChild)
- node.parentNode.normalize()
-
-
-def normalize(doc):
- for node in doc.childNodes:
- if node.nodeType == ELEMENT:
- node.normalize()
-
-
-def cleanup_trailing_parens(doc, element_names):
- d = {}
- for gi in element_names:
- d[gi] = gi
- rewrite_element = d.has_key
- queue = [node for node in doc.childNodes if node.nodeType == ELEMENT]
- while queue:
- node = queue[0]
- del queue[0]
- if rewrite_element(node.tagName):
- lastchild = node.lastChild
- if lastchild and lastchild.nodeType == TEXT:
- data = lastchild.data
- if data.endswith("()"):
- lastchild.data = data[:-2]
- else:
- for child in node.childNodes:
- if child.nodeType == ELEMENT:
- queue.append(child)
-
-
-def contents_match(left, right):
- left_children = left.childNodes
- right_children = right.childNodes
- if len(left_children) != len(right_children):
- return 0
- for l, r in map(None, left_children, right_children):
- nodeType = l.nodeType
- if nodeType != r.nodeType:
- return 0
- if nodeType == ELEMENT:
- if l.tagName != r.tagName:
- return 0
- # should check attributes, but that's not a problem here
- if not contents_match(l, r):
- return 0
- elif nodeType == TEXT:
- if l.data != r.data:
- return 0
- else:
- # not quite right, but good enough
- return 0
- return 1
-
-
-def create_module_info(doc, section):
- # Heavy.
- node = extract_first_element(section, "modulesynopsis")
- if node is None:
- return
- set_tagName(node, "synopsis")
- lastchild = node.childNodes[-1]
- if lastchild.nodeType == TEXT \
- and lastchild.data[-1:] == ".":
- lastchild.data = lastchild.data[:-1]
- modauthor = extract_first_element(section, "moduleauthor")
- if modauthor:
- set_tagName(modauthor, "author")
- modauthor.appendChild(doc.createTextNode(
- modauthor.getAttribute("name")))
- modauthor.removeAttribute("name")
- platform = extract_first_element(section, "platform")
- if section.tagName == "section":
- modinfo_pos = 2
- modinfo = doc.createElement("moduleinfo")
- moddecl = extract_first_element(section, "declaremodule")
- name = None
- if moddecl:
- modinfo.appendChild(doc.createTextNode("\n "))
- name = moddecl.attributes["name"].value
- namenode = doc.createElement("name")
- namenode.appendChild(doc.createTextNode(name))
- modinfo.appendChild(namenode)
- type = moddecl.attributes.get("type")
- if type:
- type = type.value
- modinfo.appendChild(doc.createTextNode("\n "))
- typenode = doc.createElement("type")
- typenode.appendChild(doc.createTextNode(type))
- modinfo.appendChild(typenode)
- versionadded = extract_first_element(section, "versionadded")
- if versionadded:
- modinfo.setAttribute("added", versionadded.getAttribute("version"))
- title = get_first_element(section, "title")
- if title:
- children = title.childNodes
- if len(children) >= 2 \
- and children[0].nodeName == "module" \
- and children[0].childNodes[0].data == name:
- # this is it; morph the <title> into <short-synopsis>
- first_data = children[1]
- if first_data.data[:4] == " ---":
- first_data.data = first_data.data[4:].lstrip()
- set_tagName(title, "short-synopsis")
- if children[-1].nodeType == TEXT \
- and children[-1].data[-1:] == ".":
- children[-1].data = children[-1].data[:-1]
- section.removeChild(title)
- section.removeChild(section.childNodes[0])
- title.removeChild(children[0])
- modinfo_pos = 0
- else:
- ewrite("module name in title doesn't match"
- " <declaremodule/>; no <short-synopsis/>\n")
- else:
- ewrite("Unexpected condition: <section/> without <title/>\n")
- modinfo.appendChild(doc.createTextNode("\n "))
- modinfo.appendChild(node)
- if title and not contents_match(title, node):
- # The short synopsis is actually different,
- # and needs to be stored:
- modinfo.appendChild(doc.createTextNode("\n "))
- modinfo.appendChild(title)
- if modauthor:
- modinfo.appendChild(doc.createTextNode("\n "))
- modinfo.appendChild(modauthor)
- if platform:
- modinfo.appendChild(doc.createTextNode("\n "))
- modinfo.appendChild(platform)
- modinfo.appendChild(doc.createTextNode("\n "))
- section.insertBefore(modinfo, section.childNodes[modinfo_pos])
- section.insertBefore(doc.createTextNode("\n "), modinfo)
- #
- # The rest of this removes extra newlines from where we cut out
- # a lot of elements. A lot of code for minimal value, but keeps
- # keeps the generated *ML from being too funny looking.
- #
- section.normalize()
- children = section.childNodes
- for i in range(len(children)):
- node = children[i]
- if node.nodeName == "moduleinfo":
- nextnode = children[i+1]
- if nextnode.nodeType == TEXT:
- data = nextnode.data
- s = data.lstrip()
- if len(s) < (len(data) - 4):
- nextnode.data = "\n\n\n" + s
-
-
-def cleanup_synopses(doc, fragment):
- for node in find_all_elements(fragment, "section"):
- create_module_info(doc, node)
-
-
-def fixup_table_structures(doc, fragment):
- for table in find_all_elements(fragment, "table"):
- fixup_table(doc, table)
-
-
-def fixup_table(doc, table):
- # create the table head
- thead = doc.createElement("thead")
- row = doc.createElement("row")
- move_elements_by_name(doc, table, row, "entry")
- thead.appendChild(doc.createTextNode("\n "))
- thead.appendChild(row)
- thead.appendChild(doc.createTextNode("\n "))
- # create the table body
- tbody = doc.createElement("tbody")
- prev_row = None
- last_was_hline = 0
- children = table.childNodes
- for child in children:
- if child.nodeType == ELEMENT:
- tagName = child.tagName
- if tagName == "hline" and prev_row is not None:
- prev_row.setAttribute("rowsep", "1")
- elif tagName == "row":
- prev_row = child
- # save the rows:
- tbody.appendChild(doc.createTextNode("\n "))
- move_elements_by_name(doc, table, tbody, "row", sep="\n ")
- # and toss the rest:
- while children:
- child = children[0]
- nodeType = child.nodeType
- if nodeType == TEXT:
- if child.data.strip():
- raise ConversionError("unexpected free data in <%s>: %r"
- % (table.tagName, child.data))
- table.removeChild(child)
- continue
- if nodeType == ELEMENT:
- if child.tagName != "hline":
- raise ConversionError(
- "unexpected <%s> in table" % child.tagName)
- table.removeChild(child)
- continue
- raise ConversionError(
- "unexpected %s node in table" % child.__class__.__name__)
- # nothing left in the <table>; add the <thead> and <tbody>
- tgroup = doc.createElement("tgroup")
- tgroup.appendChild(doc.createTextNode("\n "))
- tgroup.appendChild(thead)
- tgroup.appendChild(doc.createTextNode("\n "))
- tgroup.appendChild(tbody)
- tgroup.appendChild(doc.createTextNode("\n "))
- table.appendChild(tgroup)
- # now make the <entry>s look nice:
- for row in table.getElementsByTagName("row"):
- fixup_row(doc, row)
-
-
-def fixup_row(doc, row):
- entries = []
- map(entries.append, row.childNodes[1:])
- for entry in entries:
- row.insertBefore(doc.createTextNode("\n "), entry)
-# row.appendChild(doc.createTextNode("\n "))
-
-
-def move_elements_by_name(doc, source, dest, name, sep=None):
- nodes = []
- for child in source.childNodes:
- if child.nodeName == name:
- nodes.append(child)
- for node in nodes:
- source.removeChild(node)
- dest.appendChild(node)
- if sep:
- dest.appendChild(doc.createTextNode(sep))
-
-
-RECURSE_INTO_PARA_CONTAINERS = (
- "chapter", "abstract", "enumerate",
- "section", "subsection", "subsubsection",
- "paragraph", "subparagraph", "back-matter",
- "howto", "manual",
- "item", "itemize", "fulllineitems", "enumeration", "descriptionlist",
- "definitionlist", "definition",
- )
-
-PARA_LEVEL_ELEMENTS = (
- "moduleinfo", "title", "verbatim", "enumerate", "item",
- "interpreter-session", "back-matter", "interactive-session",
- "opcodedesc", "classdesc", "datadesc",
- "cfuncdesc", "ctypedesc", "cvardesc",
- "funcdesc", "methoddesc", "excdesc", "memberdesc", "membderdescni",
- "funcdescni", "methoddescni", "excdescni",
- "tableii", "tableiii", "tableiv", "localmoduletable",
- "sectionauthor", "seealso", "itemize",
- # include <para>, so we can just do it again to get subsequent paras:
- PARA_ELEMENT,
- )
-
-PARA_LEVEL_PRECEEDERS = (
- "setindexsubitem", "author",
- "stindex", "obindex", "COMMENT", "label", "xi:include", "title",
- "versionadded", "versionchanged", "declaremodule", "modulesynopsis",
- "moduleauthor", "indexterm", "leader",
- )
-
-
-def fixup_paras(doc, fragment):
- for child in fragment.childNodes:
- if child.nodeName in RECURSE_INTO_PARA_CONTAINERS:
- fixup_paras_helper(doc, child)
- descriptions = find_all_elements(fragment, "description")
- for description in descriptions:
- fixup_paras_helper(doc, description)
-
-
-def fixup_paras_helper(doc, container, depth=0):
- # document is already normalized
- children = container.childNodes
- start = skip_leading_nodes(children)
- while len(children) > start:
- if children[start].nodeName in RECURSE_INTO_PARA_CONTAINERS:
- # Something to recurse into:
- fixup_paras_helper(doc, children[start])
- else:
- # Paragraph material:
- build_para(doc, container, start, len(children))
- if DEBUG_PARA_FIXER and depth == 10:
- sys.exit(1)
- start = skip_leading_nodes(children, start + 1)
-
-
-def build_para(doc, parent, start, i):
- children = parent.childNodes
- after = start + 1
- have_last = 0
- BREAK_ELEMENTS = PARA_LEVEL_ELEMENTS + RECURSE_INTO_PARA_CONTAINERS
- # Collect all children until \n\n+ is found in a text node or a
- # member of BREAK_ELEMENTS is found.
- for j in range(start, i):
- after = j + 1
- child = children[j]
- nodeType = child.nodeType
- if nodeType == ELEMENT:
- if child.tagName in BREAK_ELEMENTS:
- after = j
- break
- elif nodeType == TEXT:
- pos = child.data.find("\n\n")
- if pos == 0:
- after = j
- break
- if pos >= 1:
- child.splitText(pos)
- break
- else:
- have_last = 1
- if (start + 1) > after:
- raise ConversionError(
- "build_para() could not identify content to turn into a paragraph")
- if children[after - 1].nodeType == TEXT:
- # we may need to split off trailing white space:
- child = children[after - 1]
- data = child.data
- if data.rstrip() != data:
- have_last = 0
- child.splitText(len(data.rstrip()))
- para = doc.createElement(PARA_ELEMENT)
- prev = None
- indexes = range(start, after)
- indexes.reverse()
- for j in indexes:
- node = parent.childNodes[j]
- parent.removeChild(node)
- para.insertBefore(node, prev)
- prev = node
- if have_last:
- parent.appendChild(para)
- parent.appendChild(doc.createTextNode("\n\n"))
- return len(parent.childNodes)
- else:
- nextnode = parent.childNodes[start]
- if nextnode.nodeType == TEXT:
- if nextnode.data and nextnode.data[0] != "\n":
- nextnode.data = "\n" + nextnode.data
- else:
- newnode = doc.createTextNode("\n")
- parent.insertBefore(newnode, nextnode)
- nextnode = newnode
- start = start + 1
- parent.insertBefore(para, nextnode)
- return start + 1
-
-
-def skip_leading_nodes(children, start=0):
- """Return index into children of a node at which paragraph building should
- begin or a recursive call to fixup_paras_helper() should be made (for
- subsections, etc.).
-
- When the return value >= len(children), we've built all the paras we can
- from this list of children.
- """
- i = len(children)
- while i > start:
- # skip over leading comments and whitespace:
- child = children[start]
- nodeType = child.nodeType
- if nodeType == TEXT:
- data = child.data
- shortened = data.lstrip()
- if shortened:
- if data != shortened:
- # break into two nodes: whitespace and non-whitespace
- child.splitText(len(data) - len(shortened))
- return start + 1
- return start
- # all whitespace, just skip
- elif nodeType == ELEMENT:
- tagName = child.tagName
- if tagName in RECURSE_INTO_PARA_CONTAINERS:
- return start
- if tagName not in PARA_LEVEL_ELEMENTS + PARA_LEVEL_PRECEEDERS:
- return start
- start = start + 1
- return start
-
-
-def fixup_rfc_references(doc, fragment):
- for rfcnode in find_all_elements_from_set(fragment, ("pep", "rfc")):
- rfcnode.appendChild(doc.createTextNode(
- rfcnode.tagName.upper() + " " + rfcnode.getAttribute("num")))
-
-
-def fixup_signatures(doc, fragment):
- for child in fragment.childNodes:
- if child.nodeType == ELEMENT:
- args = child.getElementsByTagName("args")
- for arg in args:
- rewrite_args(doc, arg)
- args = child.getElementsByTagName("constructor-args")
- for arg in args:
- rewrite_args(doc, arg)
-
-def rewrite_args(doc, arglist):
- fixup_args(doc, arglist)
- arglist.normalize()
- if arglist.childNodes.length == 1 and arglist.firstChild.nodeType == TEXT:
- node = arglist.firstChild
- node.data = ' '.join(node.data.split())
-
-def fixup_args(doc, arglist):
- for child in arglist.childNodes:
- if child.nodeName == "optional":
- # found it; fix and return
- arglist.insertBefore(doc.createTextNode("["), child)
- optkids = child.childNodes
- while optkids:
- arglist.insertBefore(child.firstChild, child)
- arglist.insertBefore(doc.createTextNode("]"), child)
- arglist.removeChild(child)
- return fixup_args(doc, arglist)
-
-
-def fixup_sectionauthors(doc, fragment):
- for sectauth in find_all_elements(fragment, "sectionauthor"):
- section = sectauth.parentNode
- section.removeChild(sectauth)
- set_tagName(sectauth, "author")
- sectauth.appendChild(doc.createTextNode(
- sectauth.getAttribute("name")))
- sectauth.removeAttribute("name")
- after = section.childNodes[2]
- title = section.childNodes[1]
- if title.nodeName != "title":
- after = section.childNodes[0]
- section.insertBefore(doc.createTextNode("\n "), after)
- section.insertBefore(sectauth, after)
-
-
-def fixup_verbatims(doc):
- for verbatim in find_all_elements(doc, "verbatim"):
- child = verbatim.childNodes[0]
- if child.nodeType == TEXT \
- and child.data.lstrip().startswith(">>>"):
- set_tagName(verbatim, "interactive-session")
-
-
-def add_node_ids(fragment, counter=0):
- fragment.node_id = counter
- for node in fragment.childNodes:
- counter = counter + 1
- if node.nodeType == ELEMENT:
- counter = add_node_ids(node, counter)
- else:
- node.node_id = counter
- return counter + 1
-
-
-def fixup_ulink(doc, fragment):
- for ulink in find_all_elements(fragment, "ulink"):
- children = ulink.childNodes
- assert len(children) == 2
- text = children[0]
- href = children[1]
- href.normalize()
- assert len(href.childNodes) == 1
- assert href.childNodes[0].nodeType == TEXT
- url = href.childNodes[0].data
- ulink.setAttribute("href", url)
- ulink.removeChild(href)
- content = text.childNodes
- while len(content):
- ulink.appendChild(content[0])
- ulink.removeChild(text)
-
-
-REFMODINDEX_ELEMENTS = ('refmodindex', 'refbimodindex',
- 'refexmodindex', 'refstmodindex')
-
-def fixup_refmodindexes(fragment):
- # Locate <ref*modindex>...</> co-located with <module>...</>, and
- # remove the <ref*modindex>, replacing it with index=index on the
- # <module> element.
- nodes = find_all_elements_from_set(fragment, REFMODINDEX_ELEMENTS)
- d = {}
- for node in nodes:
- parent = node.parentNode
- d[parent.node_id] = parent
- del nodes
- map(fixup_refmodindexes_chunk, d.values())
-
-
-def fixup_refmodindexes_chunk(container):
- # node is probably a <para>; let's see how often it isn't:
- if container.tagName != PARA_ELEMENT:
- bwrite("--- fixup_refmodindexes_chunk(%s)\n" % container)
- module_entries = find_all_elements(container, "module")
- if not module_entries:
- return
- index_entries = find_all_elements_from_set(container, REFMODINDEX_ELEMENTS)
- removes = []
- for entry in index_entries:
- children = entry.childNodes
- if len(children) != 0:
- bwrite("--- unexpected number of children for %s node:\n"
- % entry.tagName)
- ewrite(entry.toxml() + "\n")
- continue
- found = 0
- module_name = entry.getAttribute("module")
- for node in module_entries:
- if len(node.childNodes) != 1:
- continue
- this_name = node.childNodes[0].data
- if this_name == module_name:
- found = 1
- node.setAttribute("index", "yes")
- if found:
- removes.append(entry)
- for node in removes:
- container.removeChild(node)
-
-
-def fixup_bifuncindexes(fragment):
- nodes = find_all_elements(fragment, 'bifuncindex')
- d = {}
- # make sure that each parent is only processed once:
- for node in nodes:
- parent = node.parentNode
- d[parent.node_id] = parent
- del nodes
- map(fixup_bifuncindexes_chunk, d.values())
-
-
-def fixup_bifuncindexes_chunk(container):
- removes = []
- entries = find_all_child_elements(container, "bifuncindex")
- function_entries = find_all_child_elements(container, "function")
- for entry in entries:
- function_name = entry.getAttribute("name")
- found = 0
- for func_entry in function_entries:
- t2 = func_entry.childNodes[0].data
- if t2[-2:] != "()":
- continue
- t2 = t2[:-2]
- if t2 == function_name:
- func_entry.setAttribute("index", "yes")
- func_entry.setAttribute("module", "__builtin__")
- if not found:
- found = 1
- removes.append(entry)
- for entry in removes:
- container.removeChild(entry)
-
-
-def join_adjacent_elements(container, gi):
- queue = [container]
- while queue:
- parent = queue.pop()
- i = 0
- children = parent.childNodes
- nchildren = len(children)
- while i < (nchildren - 1):
- child = children[i]
- if child.nodeName == gi:
- if children[i+1].nodeName == gi:
- ewrite("--- merging two <%s/> elements\n" % gi)
- child = children[i]
- nextchild = children[i+1]
- nextchildren = nextchild.childNodes
- while len(nextchildren):
- node = nextchildren[0]
- nextchild.removeChild(node)
- child.appendChild(node)
- parent.removeChild(nextchild)
- continue
- if child.nodeType == ELEMENT:
- queue.append(child)
- i = i + 1
-
-
-_token_rx = re.compile(r"[a-zA-Z][a-zA-Z0-9.-]*$")
-
-def write_esis(doc, ofp, knownempty):
- for node in doc.childNodes:
- nodeType = node.nodeType
- if nodeType == ELEMENT:
- gi = node.tagName
- if knownempty(gi):
- if node.hasChildNodes():
- raise ValueError("declared-empty node <%s> has children" % gi)
- ofp.write("e\n")
- for k, value in node.attributes.items():
- if _token_rx.match(value):
- dtype = "TOKEN"
- else:
- dtype = "CDATA"
- ofp.write("A%s %s %s\n" % (k, dtype, esistools.encode(value)))
- ofp.write("(%s\n" % gi)
- write_esis(node, ofp, knownempty)
- ofp.write(")%s\n" % gi)
- elif nodeType == TEXT:
- ofp.write("-%s\n" % esistools.encode(node.data))
- elif nodeType == ENTITY_REFERENCE:
- ofp.write("&%s\n" % node.nodeName)
- else:
- raise RuntimeError("unsupported node type: %s" % nodeType)
-
-
-def convert(ifp, ofp):
- events = esistools.parse(ifp)
- toktype, doc = events.getEvent()
- fragment = doc.createDocumentFragment()
- events.expandNode(fragment)
-
- normalize(fragment)
- simplify(doc, fragment)
- handle_labels(doc, fragment)
- handle_appendix(doc, fragment)
- fixup_trailing_whitespace(doc, fragment, {
- # element -> (before-end-tag, after-end-tag)
- "abstract": ("\n", "\n"),
- "title": ("", "\n"),
- "chapter": ("\n", "\n\n\n"),
- "section": ("\n", "\n\n\n"),
- "subsection": ("\n", "\n\n"),
- "subsubsection": ("\n", "\n\n"),
- "paragraph": ("\n", "\n\n"),
- "subparagraph": ("\n", "\n\n"),
- "description": ("\n", "\n\n"),
- "enumeration": ("\n", "\n\n"),
- "item": ("\n", "\n\n"),
- })
- cleanup_root_text(doc)
- cleanup_trailing_parens(fragment, ["function", "method", "cfunction"])
- cleanup_synopses(doc, fragment)
- fixup_descriptors(doc, fragment)
- fixup_verbatims(fragment)
- normalize(fragment)
- fixup_paras(doc, fragment)
- fixup_sectionauthors(doc, fragment)
- fixup_table_structures(doc, fragment)
- fixup_rfc_references(doc, fragment)
- fixup_signatures(doc, fragment)
- fixup_ulink(doc, fragment)
- add_node_ids(fragment)
- fixup_refmodindexes(fragment)
- fixup_bifuncindexes(fragment)
- # Take care of ugly hacks in the LaTeX markup to avoid LaTeX and
- # LaTeX2HTML screwing with GNU-style long options (the '--' problem).
- join_adjacent_elements(fragment, "option")
- # Attempt to avoid trailing blank lines:
- fragment.normalize()
- if fragment.lastChild.data[-1:] == "\n":
- fragment.lastChild.data = fragment.lastChild.data.rstrip() + "\n"
- #
- d = {}
- for gi in events.parser.get_empties():
- d[gi] = gi
- for key in ("author", "pep", "rfc"):
- if key in d:
- del d[key]
- knownempty = d.has_key
- #
- try:
- write_esis(fragment, ofp, knownempty)
- except IOError as e:
- (err, msg) = e
- # Ignore EPIPE; it just means that whoever we're writing to stopped
- # reading. The rest of the output would be ignored. All other errors
- # should still be reported,
- if err != errno.EPIPE:
- raise
-
-
-def main():
- if len(sys.argv) == 1:
- ifp = sys.stdin
- ofp = sys.stdout
- elif len(sys.argv) == 2:
- ifp = open(sys.argv[1])
- ofp = sys.stdout
- elif len(sys.argv) == 3:
- ifp = open(sys.argv[1])
- import io
- ofp = io.StringIO()
- else:
- usage()
- sys.exit(2)
- convert(ifp, ofp)
- if len(sys.argv) == 3:
- fp = open(sys.argv[2], "w")
- fp.write(ofp.getvalue())
- fp.close()
- ofp.close()
-
-
-if __name__ == "__main__":
- main()
diff --git a/Doc/tools/sgmlconv/esis2sgml.py b/Doc/tools/sgmlconv/esis2sgml.py
deleted file mode 100755
index 10ec83a..0000000
--- a/Doc/tools/sgmlconv/esis2sgml.py
+++ /dev/null
@@ -1,263 +0,0 @@
-#! /usr/bin/env python
-
-"""Convert ESIS events to SGML or XML markup.
-
-This is limited, but seems sufficient for the ESIS generated by the
-latex2esis.py script when run over the Python documentation.
-"""
-
-# This should have an explicit option to indicate whether the *INPUT* was
-# generated from an SGML or an XML application.
-
-import errno
-import os
-import re
-import string
-
-from xml.sax.saxutils import escape
-
-import esistools
-
-
-AUTOCLOSE = ()
-
-EMPTIES_FILENAME = "../sgml/empties.dat"
-LIST_EMPTIES = 0
-
-
-_elem_map = {}
-_attr_map = {}
-_token_map = {}
-
-_normalize_case = str
-
-def map_gi(sgmlgi, map):
- uncased = _normalize_case(sgmlgi)
- try:
- return map[uncased]
- except IndexError:
- map[uncased] = sgmlgi
- return sgmlgi
-
-def null_map_gi(sgmlgi, map):
- return sgmlgi
-
-
-def format_attrs(attrs, xml=0):
- attrs = sorted(attrs.items())
- parts = []
- append = parts.append
- for name, value in attrs:
- if xml:
- append('%s="%s"' % (name, escape(value)))
- else:
- # this is a little bogus, but should do for now
- if name == value and isnmtoken(value):
- append(value)
- elif istoken(value):
- if value == "no" + name:
- append(value)
- else:
- append("%s=%s" % (name, value))
- else:
- append('%s="%s"' % (name, escape(value)))
- if parts:
- parts.insert(0, '')
- return " ".join(parts)
-
-
-_nmtoken_rx = re.compile("[a-z][-._a-z0-9]*$", re.IGNORECASE)
-def isnmtoken(s):
- return _nmtoken_rx.match(s) is not None
-
-_token_rx = re.compile("[a-z0-9][-._a-z0-9]*$", re.IGNORECASE)
-def istoken(s):
- return _token_rx.match(s) is not None
-
-
-def convert(ifp, ofp, xml=0, autoclose=(), verbatims=()):
- if xml:
- autoclose = ()
- attrs = {}
- lastopened = None
- knownempties = []
- knownempty = 0
- lastempty = 0
- inverbatim = 0
- while 1:
- line = ifp.readline()
- if not line:
- break
-
- type = line[0]
- data = line[1:]
- if data and data[-1] == "\n":
- data = data[:-1]
- if type == "-":
- data = esistools.decode(data)
- data = escape(data)
- if not inverbatim:
- data = data.replace("---", "&mdash;")
- ofp.write(data)
- if "\n" in data:
- lastopened = None
- knownempty = 0
- lastempty = 0
- elif type == "(":
- if data == "COMMENT":
- ofp.write("<!--")
- continue
- data = map_gi(data, _elem_map)
- if knownempty and xml:
- ofp.write("<%s%s/>" % (data, format_attrs(attrs, xml)))
- else:
- ofp.write("<%s%s>" % (data, format_attrs(attrs, xml)))
- if knownempty and data not in knownempties:
- # accumulate knowledge!
- knownempties.append(data)
- attrs = {}
- lastopened = data
- lastempty = knownempty
- knownempty = 0
- inverbatim = data in verbatims
- elif type == ")":
- if data == "COMMENT":
- ofp.write("-->")
- continue
- data = map_gi(data, _elem_map)
- if xml:
- if not lastempty:
- ofp.write("</%s>" % data)
- elif data not in knownempties:
- if data in autoclose:
- pass
- elif lastopened == data:
- ofp.write("</>")
- else:
- ofp.write("</%s>" % data)
- lastopened = None
- lastempty = 0
- inverbatim = 0
- elif type == "A":
- name, type, value = data.split(" ", 2)
- name = map_gi(name, _attr_map)
- attrs[name] = esistools.decode(value)
- elif type == "e":
- knownempty = 1
- elif type == "&":
- ofp.write("&%s;" % data)
- knownempty = 0
- else:
- raise RuntimeError("unrecognized ESIS event type: '%s'" % type)
-
- if LIST_EMPTIES:
- dump_empty_element_names(knownempties)
-
-
-def dump_empty_element_names(knownempties):
- d = {}
- for gi in knownempties:
- d[gi] = gi
- knownempties.append("")
- if os.path.isfile(EMPTIES_FILENAME):
- fp = open(EMPTIES_FILENAME)
- while 1:
- line = fp.readline()
- if not line:
- break
- gi = line.strip()
- if gi:
- d[gi] = gi
- fp = open(EMPTIES_FILENAME, "w")
- gilist = sorted(d.keys())
- fp.write("\n".join(gilist))
- fp.write("\n")
- fp.close()
-
-
-def update_gi_map(map, names, fromsgml=1):
- for name in names.split(","):
- if fromsgml:
- uncased = name.lower()
- else:
- uncased = name
- map[uncased] = name
-
-
-def main():
- import getopt
- import sys
- #
- autoclose = AUTOCLOSE
- xml = 1
- xmldecl = 0
- elem_names = ''
- attr_names = ''
- value_names = ''
- verbatims = ('verbatim', 'interactive-session')
- opts, args = getopt.getopt(sys.argv[1:], "adesx",
- ["autoclose=", "declare", "sgml", "xml",
- "elements-map=", "attributes-map",
- "values-map="])
- for opt, arg in opts:
- if opt in ("-d", "--declare"):
- xmldecl = 1
- elif opt == "-e":
- global LIST_EMPTIES
- LIST_EMPTIES = 1
- elif opt in ("-s", "--sgml"):
- xml = 0
- elif opt in ("-x", "--xml"):
- xml = 1
- elif opt in ("-a", "--autoclose"):
- autoclose = arg.split(",")
- elif opt == "--elements-map":
- elem_names = ("%s,%s" % (elem_names, arg))[1:]
- elif opt == "--attributes-map":
- attr_names = ("%s,%s" % (attr_names, arg))[1:]
- elif opt == "--values-map":
- value_names = ("%s,%s" % (value_names, arg))[1:]
- #
- # open input streams:
- #
- if len(args) == 0:
- ifp = sys.stdin
- ofp = sys.stdout
- elif len(args) == 1:
- ifp = open(args[0])
- ofp = sys.stdout
- elif len(args) == 2:
- ifp = open(args[0])
- ofp = open(args[1], "w")
- else:
- usage()
- sys.exit(2)
- #
- # setup the name maps:
- #
- if elem_names or attr_names or value_names:
- # assume the origin was SGML; ignore case of the names from the ESIS
- # stream but set up conversion tables to get the case right on output
- global _normalize_case
- _normalize_case = string.lower
- update_gi_map(_elem_map, elem_names.split(","))
- update_gi_map(_attr_map, attr_names.split(","))
- update_gi_map(_values_map, value_names.split(","))
- else:
- global map_gi
- map_gi = null_map_gi
- #
- # run the conversion:
- #
- try:
- if xml and xmldecl:
- opf.write('<?xml version="1.0" encoding="iso8859-1"?>\n')
- convert(ifp, ofp, xml=xml, autoclose=autoclose, verbatims=verbatims)
- except IOError as e:
- (err, msg) = e
- if err != errno.EPIPE:
- raise
-
-
-if __name__ == "__main__":
- main()
diff --git a/Doc/tools/sgmlconv/esistools.py b/Doc/tools/sgmlconv/esistools.py
deleted file mode 100644
index 11f458e..0000000
--- a/Doc/tools/sgmlconv/esistools.py
+++ /dev/null
@@ -1,312 +0,0 @@
-"""Miscellaneous utility functions useful for dealing with ESIS streams."""
-
-import re
-
-import xml.dom.pulldom
-
-import xml.sax
-import xml.sax.handler
-import xml.sax.xmlreader
-
-
-_data_match = re.compile(r"[^\\][^\\]*").match
-
-def decode(s):
- r = ''
- while s:
- m = _data_match(s)
- if m:
- r = r + m.group()
- s = s[m.end():]
- elif s[1] == "\\":
- r = r + "\\"
- s = s[2:]
- elif s[1] == "n":
- r = r + "\n"
- s = s[2:]
- elif s[1] == "%":
- s = s[2:]
- n, s = s.split(";", 1)
- r = r + unichr(int(n))
- else:
- raise ValueError("can't handle %r" % s)
- return r
-
-
-_charmap = {}
-for c in range(128):
- _charmap[chr(c)] = chr(c)
- _charmap[unichr(c + 128)] = chr(c + 128)
-_charmap["\n"] = r"\n"
-_charmap["\\"] = r"\\"
-del c
-
-_null_join = ''.join
-def encode(s):
- try:
- return _null_join(map(_charmap.get, s))
- except TypeError:
- raise Exception("could not encode %r: %r" % (s, map(_charmap.get, s)))
-
-
-class ESISReader(xml.sax.xmlreader.XMLReader):
- """SAX Reader which reads from an ESIS stream.
-
- No verification of the document structure is performed by the
- reader; a general verifier could be used as the target
- ContentHandler instance.
-
- """
- _decl_handler = None
- _lexical_handler = None
-
- _public_id = None
- _system_id = None
-
- _buffer = ""
- _is_empty = 0
- _lineno = 0
- _started = 0
-
- def __init__(self, contentHandler=None, errorHandler=None):
- xml.sax.xmlreader.XMLReader.__init__(self)
- self._attrs = {}
- self._attributes = Attributes(self._attrs)
- self._locator = Locator()
- self._empties = {}
- if contentHandler:
- self.setContentHandler(contentHandler)
- if errorHandler:
- self.setErrorHandler(errorHandler)
-
- def get_empties(self):
- return list(self._empties.keys())
-
- #
- # XMLReader interface
- #
-
- def parse(self, source):
- raise RuntimeError
- self._locator._public_id = source.getPublicId()
- self._locator._system_id = source.getSystemId()
- fp = source.getByteStream()
- handler = self.getContentHandler()
- if handler:
- handler.startDocument()
- lineno = 0
- while 1:
- token, data = self._get_token(fp)
- if token is None:
- break
- lineno = lineno + 1
- self._locator._lineno = lineno
- self._handle_token(token, data)
- handler = self.getContentHandler()
- if handler:
- handler.startDocument()
-
- def feed(self, data):
- if not self._started:
- handler = self.getContentHandler()
- if handler:
- handler.startDocument()
- self._started = 1
- data = self._buffer + data
- self._buffer = None
- lines = data.split("\n")
- if lines:
- for line in lines[:-1]:
- self._lineno = self._lineno + 1
- self._locator._lineno = self._lineno
- if not line:
- e = xml.sax.SAXParseException(
- "ESIS input line contains no token type mark",
- None, self._locator)
- self.getErrorHandler().error(e)
- else:
- self._handle_token(line[0], line[1:])
- self._buffer = lines[-1]
- else:
- self._buffer = ""
-
- def close(self):
- handler = self.getContentHandler()
- if handler:
- handler.endDocument()
- self._buffer = ""
-
- def _get_token(self, fp):
- try:
- line = fp.readline()
- except IOError as e:
- e = SAXException("I/O error reading input stream", e)
- self.getErrorHandler().fatalError(e)
- return
- if not line:
- return None, None
- if line[-1] == "\n":
- line = line[:-1]
- if not line:
- e = xml.sax.SAXParseException(
- "ESIS input line contains no token type mark",
- None, self._locator)
- self.getErrorHandler().error(e)
- return
- return line[0], line[1:]
-
- def _handle_token(self, token, data):
- handler = self.getContentHandler()
- if token == '-':
- if data and handler:
- handler.characters(decode(data))
- elif token == ')':
- if handler:
- handler.endElement(decode(data))
- elif token == '(':
- if self._is_empty:
- self._empties[data] = 1
- self._is_empty = 0
- if handler:
- handler.startElement(data, self._attributes)
- self._attrs.clear()
- elif token == 'A':
- name, value = data.split(' ', 1)
- if value != "IMPLIED":
- type, value = value.split(' ', 1)
- self._attrs[name] = (decode(value), type)
- elif token == '&':
- # entity reference in SAX?
- pass
- elif token == '?':
- if handler:
- if ' ' in data:
- target, data = data.split(None, 1)
- else:
- target, data = data, ""
- handler.processingInstruction(target, decode(data))
- elif token == 'N':
- handler = self.getDTDHandler()
- if handler:
- handler.notationDecl(data, self._public_id, self._system_id)
- self._public_id = None
- self._system_id = None
- elif token == 'p':
- self._public_id = decode(data)
- elif token == 's':
- self._system_id = decode(data)
- elif token == 'e':
- self._is_empty = 1
- elif token == 'C':
- pass
- else:
- e = SAXParseException("unknown ESIS token in event stream",
- None, self._locator)
- self.getErrorHandler().error(e)
-
- def setContentHandler(self, handler):
- old = self.getContentHandler()
- if old:
- old.setDocumentLocator(None)
- if handler:
- handler.setDocumentLocator(self._locator)
- xml.sax.xmlreader.XMLReader.setContentHandler(self, handler)
-
- def getProperty(self, property):
- if property == xml.sax.handler.property_lexical_handler:
- return self._lexical_handler
-
- elif property == xml.sax.handler.property_declaration_handler:
- return self._decl_handler
-
- else:
- raise xml.sax.SAXNotRecognizedException("unknown property %r"
- % (property, ))
-
- def setProperty(self, property, value):
- if property == xml.sax.handler.property_lexical_handler:
- if self._lexical_handler:
- self._lexical_handler.setDocumentLocator(None)
- if value:
- value.setDocumentLocator(self._locator)
- self._lexical_handler = value
-
- elif property == xml.sax.handler.property_declaration_handler:
- if self._decl_handler:
- self._decl_handler.setDocumentLocator(None)
- if value:
- value.setDocumentLocator(self._locator)
- self._decl_handler = value
-
- else:
- raise xml.sax.SAXNotRecognizedException()
-
- def getFeature(self, feature):
- if feature == xml.sax.handler.feature_namespaces:
- return 1
- else:
- return xml.sax.xmlreader.XMLReader.getFeature(self, feature)
-
- def setFeature(self, feature, enabled):
- if feature == xml.sax.handler.feature_namespaces:
- pass
- else:
- xml.sax.xmlreader.XMLReader.setFeature(self, feature, enabled)
-
-
-class Attributes(xml.sax.xmlreader.AttributesImpl):
- # self._attrs has the form {name: (value, type)}
-
- def getType(self, name):
- return self._attrs[name][1]
-
- def getValue(self, name):
- return self._attrs[name][0]
-
- def getValueByQName(self, name):
- return self._attrs[name][0]
-
- def __getitem__(self, name):
- return self._attrs[name][0]
-
- def get(self, name, default=None):
- if name in self._attrs:
- return self._attrs[name][0]
- return default
-
- def items(self):
- L = []
- for name, (value, type) in self._attrs.items():
- L.append((name, value))
- return L
-
- def values(self):
- L = []
- for value, type in list(self._attrs.values()):
- L.append(value)
- return L
-
-
-class Locator(xml.sax.xmlreader.Locator):
- _lineno = -1
- _public_id = None
- _system_id = None
-
- def getLineNumber(self):
- return self._lineno
-
- def getPublicId(self):
- return self._public_id
-
- def getSystemId(self):
- return self._system_id
-
-
-def parse(stream_or_string, parser=None):
- if type(stream_or_string) in [type(""), type(u"")]:
- stream = open(stream_or_string)
- else:
- stream = stream_or_string
- if not parser:
- parser = ESISReader()
- return xml.dom.pulldom.DOMEventStream(stream, parser, (2 ** 14) - 20)
diff --git a/Doc/tools/sgmlconv/latex2esis.py b/Doc/tools/sgmlconv/latex2esis.py
deleted file mode 100755
index 3ee86e3..0000000
--- a/Doc/tools/sgmlconv/latex2esis.py
+++ /dev/null
@@ -1,566 +0,0 @@
-#! /usr/bin/env python
-
-"""Generate ESIS events based on a LaTeX source document and
-configuration data.
-
-The conversion is not strong enough to work with arbitrary LaTeX
-documents; it has only been designed to work with the highly stylized
-markup used in the standard Python documentation. A lot of
-information about specific markup is encoded in the control table
-passed to the convert() function; changing this table can allow this
-tool to support additional LaTeX markups.
-
-The format of the table is largely undocumented; see the commented
-headers where the table is specified in main(). There is no provision
-to load an alternate table from an external file.
-"""
-
-import errno
-import getopt
-import os
-import re
-import sys
-import xml.sax
-import xml.sax.saxutils
-
-from esistools import encode
-
-
-DEBUG = 0
-
-
-class LaTeXFormatError(Exception):
- pass
-
-
-class LaTeXStackError(LaTeXFormatError):
- def __init__(self, found, stack):
- msg = "environment close for %s doesn't match;\n stack = %s" \
- % (found, stack)
- self.found = found
- self.stack = stack[:]
- LaTeXFormatError.__init__(self, msg)
-
-
-_begin_env_rx = re.compile(r"[\\]begin{([^}]*)}")
-_end_env_rx = re.compile(r"[\\]end{([^}]*)}")
-_begin_macro_rx = re.compile(r"[\\]([a-zA-Z]+[*]?) ?({|\s*\n?)")
-_comment_rx = re.compile("%+ ?(.*)\n[ \t]*")
-_text_rx = re.compile(r"[^]~%\\{}]+")
-_optional_rx = re.compile(r"\s*[[]([^]]*)[]]", re.MULTILINE)
-# _parameter_rx is this complicated to allow {...} inside a parameter;
-# this is useful to match tabular layout specifications like {c|p{24pt}}
-_parameter_rx = re.compile("[ \n]*{(([^{}}]|{[^}]*})*)}")
-_token_rx = re.compile(r"[a-zA-Z][a-zA-Z0-9.-]*$")
-_start_group_rx = re.compile("[ \n]*{")
-_start_optional_rx = re.compile("[ \n]*[[]")
-
-
-ESCAPED_CHARS = "$%#^ {}&~"
-
-
-def dbgmsg(msg):
- if DEBUG:
- sys.stderr.write(msg + "\n")
-
-def pushing(name, point, depth):
- dbgmsg("pushing <%s> at %s" % (name, point))
-
-def popping(name, point, depth):
- dbgmsg("popping </%s> at %s" % (name, point))
-
-
-class _Stack(list):
- def append(self, entry):
- if not isinstance(entry, str):
- raise LaTeXFormatError("cannot push non-string on stack: %r"
- % (entry, ))
- #dbgmsg("%s<%s>" % (" "*len(self.data), entry))
- list.append(self, entry)
-
- def pop(self, index=-1):
- entry = self[index]
- del self[index]
- #dbgmsg("%s</%s>" % (" " * len(self), entry))
-
- def __delitem__(self, index):
- entry = self[index]
- list.__delitem__(self, index)
- #dbgmsg("%s</%s>" % (" " * len(self), entry))
-
-
-def new_stack():
- if DEBUG:
- return _Stack()
- else:
- return []
-
-
-class Conversion:
- def __init__(self, ifp, ofp, table):
- self.write = ofp.write
- self.ofp = ofp
- self.table = table
- L = [s.rstrip() for s in ifp.readlines()]
- L.append("")
- self.line = "\n".join(L)
- self.preamble = 1
-
- def convert(self):
- self.subconvert()
-
- def subconvert(self, endchar=None, depth=0):
- #
- # Parses content, including sub-structures, until the character
- # 'endchar' is found (with no open structures), or until the end
- # of the input data is endchar is None.
- #
- stack = new_stack()
- line = self.line
- while line:
- if line[0] == endchar and not stack:
- self.line = line
- return line
- m = _comment_rx.match(line)
- if m:
- text = m.group(1)
- if text:
- self.write("(COMMENT\n- %s \n)COMMENT\n-\\n\n"
- % encode(text))
- line = line[m.end():]
- continue
- m = _begin_env_rx.match(line)
- if m:
- name = m.group(1)
- entry = self.get_env_entry(name)
- # re-write to use the macro handler
- line = r"\%s %s" % (name, line[m.end():])
- continue
- m = _end_env_rx.match(line)
- if m:
- # end of environment
- envname = m.group(1)
- entry = self.get_entry(envname)
- while stack and envname != stack[-1] \
- and stack[-1] in entry.endcloses:
- self.write(")%s\n" % stack.pop())
- if stack and envname == stack[-1]:
- self.write(")%s\n" % entry.outputname)
- del stack[-1]
- else:
- raise LaTeXStackError(envname, stack)
- line = line[m.end():]
- continue
- m = _begin_macro_rx.match(line)
- if m:
- # start of macro
- macroname = m.group(1)
- if macroname == "c":
- # Ugh! This is a combining character...
- endpos = m.end()
- self.combining_char("c", line[endpos])
- line = line[endpos + 1:]
- continue
- entry = self.get_entry(macroname)
- if entry.verbatim:
- # magic case!
- pos = line.find("\\end{%s}" % macroname)
- text = line[m.end(1):pos]
- stack.append(entry.name)
- self.write("(%s\n" % entry.outputname)
- self.write("-%s\n" % encode(text))
- self.write(")%s\n" % entry.outputname)
- stack.pop()
- line = line[pos + len("\\end{%s}" % macroname):]
- continue
- while stack and stack[-1] in entry.closes:
- top = stack.pop()
- topentry = self.get_entry(top)
- if topentry.outputname:
- self.write(")%s\n-\\n\n" % topentry.outputname)
- #
- if entry.outputname and entry.empty:
- self.write("e\n")
- #
- params, optional, empty = self.start_macro(macroname)
- # rip off the macroname
- if params:
- line = line[m.end(1):]
- elif empty:
- line = line[m.end(1):]
- else:
- line = line[m.end():]
- opened = 0
- implied_content = 0
-
- # handle attribute mappings here:
- for pentry in params:
- if pentry.type == "attribute":
- if pentry.optional:
- m = _optional_rx.match(line)
- if m and entry.outputname:
- line = line[m.end():]
- self.dump_attr(pentry, m.group(1))
- elif pentry.text and entry.outputname:
- # value supplied by conversion spec:
- self.dump_attr(pentry, pentry.text)
- else:
- m = _parameter_rx.match(line)
- if not m:
- raise LaTeXFormatError(
- "could not extract parameter %s for %s: %r"
- % (pentry.name, macroname, line[:100]))
- if entry.outputname:
- self.dump_attr(pentry, m.group(1))
- line = line[m.end():]
- elif pentry.type == "child":
- if pentry.optional:
- m = _optional_rx.match(line)
- if m:
- line = line[m.end():]
- if entry.outputname and not opened:
- opened = 1
- self.write("(%s\n" % entry.outputname)
- stack.append(macroname)
- stack.append(pentry.name)
- self.write("(%s\n" % pentry.name)
- self.write("-%s\n" % encode(m.group(1)))
- self.write(")%s\n" % pentry.name)
- stack.pop()
- else:
- if entry.outputname and not opened:
- opened = 1
- self.write("(%s\n" % entry.outputname)
- stack.append(entry.name)
- self.write("(%s\n" % pentry.name)
- stack.append(pentry.name)
- self.line = skip_white(line)[1:]
- line = self.subconvert(
- "}", len(stack) + depth + 1)[1:]
- self.write(")%s\n" % stack.pop())
- elif pentry.type == "content":
- if pentry.implied:
- implied_content = 1
- else:
- if entry.outputname and not opened:
- opened = 1
- self.write("(%s\n" % entry.outputname)
- stack.append(entry.name)
- line = skip_white(line)
- if line[0] != "{":
- raise LaTeXFormatError(
- "missing content for " + macroname)
- self.line = line[1:]
- line = self.subconvert("}", len(stack) + depth + 1)
- if line and line[0] == "}":
- line = line[1:]
- elif pentry.type == "text" and pentry.text:
- if entry.outputname and not opened:
- opened = 1
- stack.append(entry.name)
- self.write("(%s\n" % entry.outputname)
- #dbgmsg("--- text: %r" % pentry.text)
- self.write("-%s\n" % encode(pentry.text))
- elif pentry.type == "entityref":
- self.write("&%s\n" % pentry.name)
- if entry.outputname:
- if not opened:
- self.write("(%s\n" % entry.outputname)
- stack.append(entry.name)
- if not implied_content:
- self.write(")%s\n" % entry.outputname)
- stack.pop()
- continue
- if line[0] == endchar and not stack:
- self.line = line[1:]
- return self.line
- if line[0] == "}":
- # end of macro or group
- macroname = stack[-1]
- if macroname:
- conversion = self.table[macroname]
- if conversion.outputname:
- # otherwise, it was just a bare group
- self.write(")%s\n" % conversion.outputname)
- del stack[-1]
- line = line[1:]
- continue
- if line[0] == "~":
- # don't worry about the "tie" aspect of this command
- line = line[1:]
- self.write("- \n")
- continue
- if line[0] == "{":
- stack.append("")
- line = line[1:]
- continue
- if line[0] == "\\" and line[1] in ESCAPED_CHARS:
- self.write("-%s\n" % encode(line[1]))
- line = line[2:]
- continue
- if line[:2] == r"\\":
- self.write("(BREAK\n)BREAK\n")
- line = line[2:]
- continue
- if line[:2] == r"\_":
- line = "_" + line[2:]
- continue
- if line[:2] in (r"\'", r'\"'):
- # combining characters...
- self.combining_char(line[1], line[2])
- line = line[3:]
- continue
- m = _text_rx.match(line)
- if m:
- text = encode(m.group())
- self.write("-%s\n" % text)
- line = line[m.end():]
- continue
- # special case because of \item[]
- # XXX can we axe this???
- if line[0] == "]":
- self.write("-]\n")
- line = line[1:]
- continue
- # avoid infinite loops
- extra = ""
- if len(line) > 100:
- extra = "..."
- raise LaTeXFormatError("could not identify markup: %r%s"
- % (line[:100], extra))
- while stack:
- entry = self.get_entry(stack[-1])
- if entry.closes:
- self.write(")%s\n-%s\n" % (entry.outputname, encode("\n")))
- del stack[-1]
- else:
- break
- if stack:
- raise LaTeXFormatError("elements remain on stack: "
- + ", ".join(stack))
- # otherwise we just ran out of input here...
-
- # This is a really limited table of combinations, but it will have
- # to do for now.
- _combinations = {
- ("c", "c"): 0x00E7,
- ("'", "e"): 0x00E9,
- ('"', "o"): 0x00F6,
- }
-
- def combining_char(self, prefix, char):
- ordinal = self._combinations[(prefix, char)]
- self.write("-\\%%%d;\n" % ordinal)
-
- def start_macro(self, name):
- conversion = self.get_entry(name)
- parameters = conversion.parameters
- optional = parameters and parameters[0].optional
- return parameters, optional, conversion.empty
-
- def get_entry(self, name):
- entry = self.table.get(name)
- if entry is None:
- dbgmsg("get_entry(%r) failing; building default entry!" % (name, ))
- # not defined; build a default entry:
- entry = TableEntry(name)
- entry.has_content = 1
- entry.parameters.append(Parameter("content"))
- self.table[name] = entry
- return entry
-
- def get_env_entry(self, name):
- entry = self.table.get(name)
- if entry is None:
- # not defined; build a default entry:
- entry = TableEntry(name, 1)
- entry.has_content = 1
- entry.parameters.append(Parameter("content"))
- entry.parameters[-1].implied = 1
- self.table[name] = entry
- elif not entry.environment:
- raise LaTeXFormatError(
- name + " is defined as a macro; expected environment")
- return entry
-
- def dump_attr(self, pentry, value):
- if not (pentry.name and value):
- return
- if _token_rx.match(value):
- dtype = "TOKEN"
- else:
- dtype = "CDATA"
- self.write("A%s %s %s\n" % (pentry.name, dtype, encode(value)))
-
-
-def convert(ifp, ofp, table):
- c = Conversion(ifp, ofp, table)
- try:
- c.convert()
- except IOError as e:
- (err, msg) = e
- if err != errno.EPIPE:
- raise
-
-
-def skip_white(line):
- while line and line[0] in " %\n\t\r":
- line = line[1:].lstrip()
- return line
-
-
-
-class TableEntry:
- def __init__(self, name, environment=0):
- self.name = name
- self.outputname = name
- self.environment = environment
- self.empty = not environment
- self.has_content = 0
- self.verbatim = 0
- self.auto_close = 0
- self.parameters = []
- self.closes = []
- self.endcloses = []
-
-class Parameter:
- def __init__(self, type, name=None, optional=0):
- self.type = type
- self.name = name
- self.optional = optional
- self.text = ''
- self.implied = 0
-
-
-class TableHandler(xml.sax.handler.ContentHandler):
- def __init__(self):
- self.__table = {}
- self.__buffer = ''
- self.__methods = {}
-
- def get_table(self):
- for entry in self.__table.values():
- if entry.environment and not entry.has_content:
- p = Parameter("content")
- p.implied = 1
- entry.parameters.append(p)
- entry.has_content = 1
- return self.__table
-
- def startElement(self, tag, attrs):
- try:
- start, end = self.__methods[tag]
- except KeyError:
- start = getattr(self, "start_" + tag, None)
- end = getattr(self, "end_" + tag, None)
- self.__methods[tag] = (start, end)
- if start:
- start(attrs)
-
- def endElement(self, tag):
- start, end = self.__methods[tag]
- if end:
- end()
-
- def endDocument(self):
- self.__methods.clear()
-
- def characters(self, data):
- self.__buffer += data
-
- def start_environment(self, attrs):
- name = attrs["name"]
- self.__current = TableEntry(name, environment=1)
- self.__current.verbatim = attrs.get("verbatim") == "yes"
- if "outputname" in attrs:
- self.__current.outputname = attrs.get("outputname")
- self.__current.endcloses = attrs.get("endcloses", "").split()
- def end_environment(self):
- self.end_macro()
-
- def start_macro(self, attrs):
- name = attrs["name"]
- self.__current = TableEntry(name)
- self.__current.closes = attrs.get("closes", "").split()
- if "outputname" in attrs:
- self.__current.outputname = attrs.get("outputname")
- def end_macro(self):
- name = self.__current.name
- if name in self.__table:
- raise ValueError("name %r already in use" % (name,))
- self.__table[name] = self.__current
- self.__current = None
-
- def start_attribute(self, attrs):
- name = attrs.get("name")
- optional = attrs.get("optional") == "yes"
- if name:
- p = Parameter("attribute", name, optional=optional)
- else:
- p = Parameter("attribute", optional=optional)
- self.__current.parameters.append(p)
- self.__buffer = ''
- def end_attribute(self):
- self.__current.parameters[-1].text = self.__buffer
-
- def start_entityref(self, attrs):
- name = attrs["name"]
- p = Parameter("entityref", name)
- self.__current.parameters.append(p)
-
- def start_child(self, attrs):
- name = attrs["name"]
- p = Parameter("child", name, attrs.get("optional") == "yes")
- self.__current.parameters.append(p)
- self.__current.empty = 0
-
- def start_content(self, attrs):
- p = Parameter("content")
- p.implied = attrs.get("implied") == "yes"
- if self.__current.environment:
- p.implied = 1
- self.__current.parameters.append(p)
- self.__current.has_content = 1
- self.__current.empty = 0
-
- def start_text(self, attrs):
- self.__current.empty = 0
- self.__buffer = ''
- def end_text(self):
- p = Parameter("text")
- p.text = self.__buffer
- self.__current.parameters.append(p)
-
-
-def load_table(fp):
- ch = TableHandler()
- xml.sax.parse(fp, ch)
- return ch.get_table()
-
-
-def main():
- global DEBUG
- #
- opts, args = getopt.getopt(sys.argv[1:], "D", ["debug"])
- for opt, arg in opts:
- if opt in ("-D", "--debug"):
- DEBUG += 1
- if len(args) == 0:
- ifp = sys.stdin
- ofp = sys.stdout
- elif len(args) == 1:
- ifp = open(args[0])
- ofp = sys.stdout
- elif len(args) == 2:
- ifp = open(args[0])
- ofp = open(args[1], "w")
- else:
- usage()
- sys.exit(2)
-
- table = load_table(open(os.path.join(sys.path[0], 'conversion.xml')))
- convert(ifp, ofp, table)
-
-
-if __name__ == "__main__":
- main()
diff --git a/Doc/tools/sgmlconv/make.rules b/Doc/tools/sgmlconv/make.rules
deleted file mode 100644
index 93579c5..0000000
--- a/Doc/tools/sgmlconv/make.rules
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- makefile -*-
-#
-# Extra magic needed by the LaTeX->XML conversion process. This requires
-# $(TOOLSDIR) to be properly defined.
-
-DOCFIXER= $(TOOLSDIR)/sgmlconv/docfixer.py
-ESIS2ML= $(TOOLSDIR)/sgmlconv/esis2sgml.py
-LATEX2ESIS= $(TOOLSDIR)/sgmlconv/latex2esis.py
-CONVERSION= $(TOOLSDIR)/sgmlconv/conversion.xml
-
-ESISTARGETS= $(patsubst %.tex,%.esis,$(wildcard *.tex))
-ESIS1TARGETS= $(patsubst %.tex,%.esis1,$(wildcard *.tex))
-XMLTARGETS= $(patsubst %.tex,%.xml,$(wildcard *.tex))
-
-L2EFLAGS=
-
-all: xml
-
-esis: $(ESISTARGETS)
-esis1: $(ESIS1TARGETS)
-xml: $(XMLTARGETS)
-
-ESISTOOLS= $(TOOLSDIR)/sgmlconv/esistools.py
-
-$(ESISTARGETS): $(LATEX2ESIS) $(DOCFIXER) $(ESISTOOLS) $(CONVERSION)
-$(ESIS1TARGETS): $(LATEX2ESIS) $(CONVERSION)
-# This variant is easier to work with while debugging the conversion spec:
-#$(ESISTARGETS): $(LATEX2ESIS) $(DOCFIXER) $(ESISTOOLS)
-$(XMLTARGETS): $(ESIS2ML)
-
-
-.SUFFIXES: .esis .esis1 .tex .xml
-
-.tex.esis1:
- $(LATEX2ESIS) $(L2EFLAGS) $< $@
-
-.esis1.esis:
- $(DOCFIXER) $< $@
-
-.esis.xml:
- $(ESIS2ML) --xml $< $@
-
-
-clean:
- rm -f *.esis *.esis1
-
-clobber: clean
- rm -f *.xml
diff --git a/Doc/tools/support.py b/Doc/tools/support.py
deleted file mode 100644
index fc4cafa..0000000
--- a/Doc/tools/support.py
+++ /dev/null
@@ -1,202 +0,0 @@
-"""Miscellaneous support code shared by some of the tool scripts.
-
-This includes option parsing code, HTML formatting code, and a couple of
-useful helpers.
-
-"""
-__version__ = '$Revision$'
-
-
-import getopt
-import os.path
-import sys
-
-
-class Options:
- __short_args = "a:c:ho:"
- __long_args = [
- # script controls
- "columns=", "help", "output=",
-
- # content components
- "address=", "iconserver=", "favicon=",
- "title=", "uplink=", "uptitle=",
- "image-type=",
- ]
-
- outputfile = "-"
- columns = 1
- letters = 0
- uplink = "index.html"
- uptitle = "Python Documentation Index"
- favicon = None
-
- # The "Aesop Meta Tag" is poorly described, and may only be used
- # by the Aesop search engine (www.aesop.com), but doesn't hurt.
- #
- # There are a number of values this may take to roughly categorize
- # a page. A page should be marked according to its primary
- # category. Known values are:
- # 'personal' -- personal-info
- # 'information' -- information
- # 'interactive' -- interactive media
- # 'multimedia' -- multimedia presenetation (non-sales)
- # 'sales' -- sales material
- # 'links' -- links to other information pages
- #
- # Setting the aesop_type value to one of these strings will cause
- # get_header() to add the appropriate <meta> tag to the <head>.
- #
- aesop_type = None
-
- def __init__(self):
- self.args = []
- self.variables = {"address": "",
- "iconserver": "icons",
- "imgtype": "png",
- "title": "Global Module Index",
- }
-
- def add_args(self, short=None, long=None):
- if short:
- self.__short_args = self.__short_args + short
- if long:
- self.__long_args = self.__long_args + long
-
- def parse(self, args):
- try:
- opts, args = getopt.getopt(args, self.__short_args,
- self.__long_args)
- except getopt.error:
- sys.stdout = sys.stderr
- self.usage()
- sys.exit(2)
- self.args = self.args + args
- for opt, val in opts:
- if opt in ("-a", "--address"):
- val = val.strip()
- if val:
- val = "<address>\n%s\n</address>\n" % val
- self.variables["address"] = val
- elif opt in ("-h", "--help"):
- self.usage()
- sys.exit()
- elif opt in ("-o", "--output"):
- self.outputfile = val
- elif opt in ("-c", "--columns"):
- self.columns = int(val)
- elif opt == "--title":
- self.variables["title"] = val.strip()
- elif opt == "--uplink":
- self.uplink = val.strip()
- elif opt == "--uptitle":
- self.uptitle = val.strip()
- elif opt == "--iconserver":
- self.variables["iconserver"] = val.strip() or "."
- elif opt == "--favicon":
- self.favicon = val.strip()
- elif opt == "--image-type":
- self.variables["imgtype"] = val.strip()
- else:
- self.handle_option(opt, val)
- if self.uplink and self.uptitle:
- self.variables["uplinkalt"] = "up"
- self.variables["uplinkicon"] = "up"
- else:
- self.variables["uplinkalt"] = ""
- self.variables["uplinkicon"] = "blank"
- self.variables["uplink"] = self.uplink
- self.variables["uptitle"] = self.uptitle
-
- def handle_option(self, opt, val):
- raise getopt.error("option %s not recognized" % opt)
-
- def get_header(self):
- s = HEAD % self.variables
- if self.uplink:
- if self.uptitle:
- link = ('<link rel="up" href="%s" title="%s">\n '
- '<link rel="start" href="%s" title="%s">'
- % (self.uplink, self.uptitle,
- self.uplink, self.uptitle))
- else:
- link = ('<link rel="up" href="%s">\n '
- '<link rel="start" href="%s">'
- % (self.uplink, self.uplink))
- repl = " %s\n</head>" % link
- s = s.replace("</head>", repl, 1)
- if self.aesop_type:
- meta = '<meta name="aesop" content="%s">\n ' % self.aesop_type
- # Insert this in the middle of the head that's been
- # generated so far, keeping <meta> and <link> elements in
- # neat groups:
- s = s.replace("<link ", meta + "<link ", 1)
- if self.favicon:
- ext = os.path.splitext(self.favicon)[1]
- if ext in (".gif", ".png"):
- type = ' type="image/%s"' % ext[1:]
- else:
- type = ''
- link = ('<link rel="SHORTCUT ICON" href="%s"%s>\n '
- % (self.favicon, type))
- s = s.replace("<link ", link + "<link ", 1)
- return s
-
- def get_footer(self):
- return TAIL % self.variables
-
- def get_output_file(self, filename=None):
- if filename is None:
- filename = self.outputfile
- if filename == "-":
- return sys.stdout
- else:
- return open(filename, "w")
-
-
-NAVIGATION = '''\
-<div class="navigation">
-<table width="100%%" cellpadding="0" cellspacing="2">
-<tr>
-<td><img width="32" height="32" align="bottom" border="0" alt=""
- src="%(iconserver)s/blank.%(imgtype)s"></td>
-<td><a href="%(uplink)s"
- title="%(uptitle)s"><img width="32" height="32" align="bottom" border="0"
- alt="%(uplinkalt)s"
- src="%(iconserver)s/%(uplinkicon)s.%(imgtype)s"></a></td>
-<td><img width="32" height="32" align="bottom" border="0" alt=""
- src="%(iconserver)s/blank.%(imgtype)s"></td>
-<td align="center" width="100%%">%(title)s</td>
-<td><img width="32" height="32" align="bottom" border="0" alt=""
- src="%(iconserver)s/blank.%(imgtype)s"></td>
-<td><img width="32" height="32" align="bottom" border="0" alt=""
- src="%(iconserver)s/blank.%(imgtype)s"></td>
-<td><img width="32" height="32" align="bottom" border="0" alt=""
- src="%(iconserver)s/blank.%(imgtype)s"></td>
-</tr></table>
-<b class="navlabel">Up:</b> <span class="sectref"><a href="%(uplink)s"
- title="%(uptitle)s">%(uptitle)s</A></span>
-<br></div>
-'''
-
-HEAD = '''\
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-<head>
- <title>%(title)s</title>
- <meta name="description" content="%(title)s">
- <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
- <link rel="STYLESHEET" href="lib/lib.css">
-</head>
-<body>
-''' + NAVIGATION + '''\
-<hr>
-
-<h2>%(title)s</h2>
-
-'''
-
-TAIL = "<hr>\n" + NAVIGATION + '''\
-%(address)s</body>
-</html>
-'''
diff --git a/Doc/tools/toc2bkm.py b/Doc/tools/toc2bkm.py
deleted file mode 100755
index ab669ba..0000000
--- a/Doc/tools/toc2bkm.py
+++ /dev/null
@@ -1,160 +0,0 @@
-#! /usr/bin/env python
-
-"""Convert a LaTeX .toc file to some PDFTeX magic to create that neat outline.
-
-The output file has an extension of '.bkm' instead of '.out', since hyperref
-already uses that extension.
-"""
-
-import getopt
-import os
-import re
-import string
-import sys
-
-
-# Ench item in an entry is a tuple of:
-#
-# Section #, Title String, Page #, List of Sub-entries
-#
-# The return value of parse_toc() is such a tuple.
-
-cline_re = r"""^
-\\contentsline\ \{([a-z]*)} # type of section in $1
-\{(?:\\numberline\ \{([0-9.A-Z]+)})? # section number
-(.*)} # title string
-\{(\d+)}$""" # page number
-
-cline_rx = re.compile(cline_re, re.VERBOSE)
-
-OUTER_TO_INNER = -1
-
-_transition_map = {
- ('chapter', 'section'): OUTER_TO_INNER,
- ('section', 'subsection'): OUTER_TO_INNER,
- ('subsection', 'subsubsection'): OUTER_TO_INNER,
- ('subsubsection', 'subsection'): 1,
- ('subsection', 'section'): 1,
- ('section', 'chapter'): 1,
- ('subsection', 'chapter'): 2,
- ('subsubsection', 'section'): 2,
- ('subsubsection', 'chapter'): 3,
- }
-
-INCLUDED_LEVELS = ("chapter", "section", "subsection", "subsubsection")
-
-
-class BadSectionNesting(Exception):
- """Raised for unsupported section level transitions."""
-
- def __init__(self, level, newsection, path, lineno):
- self.level = level
- self.newsection = newsection
- self.path = path
- self.lineno = lineno
-
- def __str__(self):
- return ("illegal transition from %s to %s at %s (line %s)"
- % (self.level, self.newsection, self.path, self.lineno))
-
-
-def parse_toc(fp, bigpart=None):
- toc = top = []
- stack = [toc]
- level = bigpart or 'chapter'
- lineno = 0
- while 1:
- line = fp.readline()
- if not line:
- break
- lineno = lineno + 1
- m = cline_rx.match(line)
- if m:
- stype, snum, title, pageno = m.group(1, 2, 3, 4)
- title = clean_title(title)
- entry = (stype, snum, title, int(pageno), [])
- if stype == level:
- toc.append(entry)
- else:
- if stype not in INCLUDED_LEVELS:
- # we don't want paragraphs & subparagraphs
- continue
- try:
- direction = _transition_map[(level, stype)]
- except KeyError:
- raise BadSectionNesting(level, stype, fp.name, lineno)
- if direction == OUTER_TO_INNER:
- toc = toc[-1][-1]
- stack.insert(0, toc)
- toc.append(entry)
- else:
- for i in range(direction):
- del stack[0]
- toc = stack[0]
- toc.append(entry)
- level = stype
- else:
- sys.stderr.write("l.%s: " + line)
- return top
-
-
-hackscore_rx = re.compile(r"\\hackscore\s*{[^}]*}")
-raisebox_rx = re.compile(r"\\raisebox\s*{[^}]*}")
-title_rx = re.compile(r"\\([a-zA-Z])+\s+")
-title_trans = string.maketrans("", "")
-
-def clean_title(title):
- title = raisebox_rx.sub("", title)
- title = hackscore_rx.sub(r"\\_", title)
- pos = 0
- while 1:
- m = title_rx.search(title, pos)
- if m:
- start = m.start()
- if title[start:start+15] != "\\textunderscore":
- title = title[:start] + title[m.end():]
- pos = start + 1
- else:
- break
- title = title.translate(title_trans, "{}")
- return title
-
-
-def write_toc(toc, fp):
- for entry in toc:
- write_toc_entry(entry, fp, 0)
-
-def write_toc_entry(entry, fp, layer):
- stype, snum, title, pageno, toc = entry
- s = "\\pdfoutline goto name{page%03d}" % pageno
- if toc:
- s = "%s count -%d" % (s, len(toc))
- if snum:
- title = "%s %s" % (snum, title)
- s = "%s {%s}\n" % (s, title)
- fp.write(s)
- for entry in toc:
- write_toc_entry(entry, fp, layer + 1)
-
-
-def process(ifn, ofn, bigpart=None):
- toc = parse_toc(open(ifn), bigpart)
- write_toc(toc, open(ofn, "w"))
-
-
-def main():
- bigpart = None
- opts, args = getopt.getopt(sys.argv[1:], "c:")
- if opts:
- bigpart = opts[0][1]
- if not args:
- usage()
- sys.exit(2)
- for filename in args:
- base, ext = os.path.splitext(filename)
- ext = ext or ".toc"
- process(base + ext, base + ".bkm", bigpart)
-
-
-if __name__ == "__main__":
- main()
diff --git a/Doc/tools/undoc_symbols.py b/Doc/tools/undoc_symbols.py
deleted file mode 100644
index 14cb941..0000000
--- a/Doc/tools/undoc_symbols.py
+++ /dev/null
@@ -1,93 +0,0 @@
-#! /usr/bin/env python
-
-"""\
-This script prints out a list of undocumented symbols found in
-Python include files, prefixed by their tag kind.
-
-Pass Python's include files to ctags, parse the output into a
-dictionary mapping symbol names to tag kinds.
-
-Then, the .tex files from Python docs are read into a giant string.
-
-Finally all symbols not found in the docs are written to standard
-output, prefixed with their tag kind.
-"""
-
-# Which kind of tags do we need?
-TAG_KINDS = "dpst"
-
-# Doc sections to use
-DOCSECTIONS = ["api"]# ["api", "ext"]
-
-# Only print symbols starting with this prefix,
-# to get all symbols, use an empty string
-PREFIXES = ("Py", "PY")
-
-INCLUDEPATTERN = "*.h"
-
-# end of customization section
-
-
-# Tested with EXUBERANT CTAGS
-# see http://ctags.sourceforge.net
-#
-# ctags fields are separated by tabs.
-# The first field is the name, the last field the type:
-# d macro definitions (and #undef names)
-# e enumerators
-# f function definitions
-# g enumeration names
-# m class, struct, or union members
-# n namespaces
-# p function prototypes and declarations
-# s structure names
-# t typedefs
-# u union names
-# v variable definitions
-# x extern and forward variable declarations
-
-import os, glob, re, sys
-
-def findnames(file, prefixes=()):
- names = {}
- for line in file:
- if line[0] == '!':
- continue
- fields = line.split()
- name, tag = fields[0], fields[-1]
- if tag == 'd' and name.endswith('_H'):
- continue
- if prefixes:
- sw = name.startswith
- for prefix in prefixes:
- if sw(prefix):
- names[name] = tag
- else:
- names[name] = tag
- return names
-
-def print_undoc_symbols(prefix, docdir, incdir):
- docs = []
-
- for sect in DOCSECTIONS:
- for file in glob.glob(os.path.join(docdir, sect, "*.tex")):
- docs.append(open(file).read())
-
- docs = "\n".join(docs)
-
- incfiles = os.path.join(incdir, INCLUDEPATTERN)
-
- fp = os.popen("ctags -IPyAPI_FUNC -IPy_GCC_ATTRIBUTE --c-types=%s -f - %s"
- % (TAG_KINDS, incfiles))
- dict = findnames(fp, prefix)
- names = sorted(dict.keys())
- for name in names:
- if not re.search("%s\\W" % name, docs):
- print(dict[name], name)
-
-if __name__ == '__main__':
- srcdir = os.path.dirname(sys.argv[0])
- incdir = os.path.normpath(os.path.join(srcdir, "../../Include"))
- docdir = os.path.normpath(os.path.join(srcdir, ".."))
-
- print_undoc_symbols(PREFIXES, docdir, incdir)
diff --git a/Doc/tools/update-docs.sh b/Doc/tools/update-docs.sh
deleted file mode 100755
index 6599c64..0000000
--- a/Doc/tools/update-docs.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#! /bin/sh
-
-# Script which installs a development snapshot of the documentation
-# into the development website.
-#
-# The push-docs.sh script pushes this to the server when needed
-# and removes it when done.
-
-if [ -z "$HOME" ] ; then
- HOME=`grep "$LOGNAME" /etc/passwd | sed 's|^.*:\([^:]*\):[^:]*$|\1|'`
- export HOME
-fi
-
-DOCTYPE="$1"
-UPDATES="$HOME/tmp/$2"
-
-TMPDIR="$$-docs"
-
-cd /ftp/ftp.python.org/pub/www.python.org/dev/doc/ || exit $?
-mkdir $TMPDIR || exit $?
-cd $TMPDIR || exit $?
-(bzip2 -dc "$UPDATES" | tar xf -) || exit $?
-cd .. || exit $?
-
-if [ -d $DOCTYPE ] ; then
- mv $DOCTYPE $DOCTYPE-temp
-fi
-mv $TMPDIR/Python-Docs-* $DOCTYPE
-rmdir $TMPDIR
-rm -rf $DOCTYPE-temp || exit $?
-mv "$UPDATES" python-docs-$DOCTYPE.tar.bz2 || exit $?
diff --git a/Doc/tools/whichlibs b/Doc/tools/whichlibs
deleted file mode 100755
index 10d44ee..0000000
--- a/Doc/tools/whichlibs
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/sh
-sed -n 's%^\\input{\(lib[a-zA-Z0-9_]*\)}.*%../lib/\1.tex%p' ../lib/lib.tex