summaryrefslogtreecommitdiff
path: root/sandbox/fwiemann
diff options
context:
space:
mode:
Diffstat (limited to 'sandbox/fwiemann')
-rw-r--r--sandbox/fwiemann/.fsfsbackup4
-rw-r--r--sandbox/fwiemann/commit-email/README.txt21
-rw-r--r--sandbox/fwiemann/commit-email/commit-email.patch135
-rwxr-xr-xsandbox/fwiemann/fsfsbackup.sh90
-rw-r--r--sandbox/fwiemann/plugins/interface.py256
-rwxr-xr-xsandbox/fwiemann/release.sh490
-rw-r--r--sandbox/fwiemann/users.txt70
-rw-r--r--sandbox/fwiemann/xhtml2rest/README.txt15
-rwxr-xr-xsandbox/fwiemann/xhtml2rest/xhtml2rest.py551
9 files changed, 0 insertions, 1632 deletions
diff --git a/sandbox/fwiemann/.fsfsbackup b/sandbox/fwiemann/.fsfsbackup
deleted file mode 100644
index 89588ab02..000000000
--- a/sandbox/fwiemann/.fsfsbackup
+++ /dev/null
@@ -1,4 +0,0 @@
-BACKUPDIR=~/remote-backup/docutils
-HOST=svn.berlios.de
-REMOTEDIR=/svnroot/repos/docutils
-do_backup
diff --git a/sandbox/fwiemann/commit-email/README.txt b/sandbox/fwiemann/commit-email/README.txt
deleted file mode 100644
index 428a569d0..000000000
--- a/sandbox/fwiemann/commit-email/README.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-=========================================
- File name patch for ``commit-email.pl``
-=========================================
-
-:Author: Felix Wiemann
-:Contact: Felix.Wiemann@ososo.de
-:Revision: $Revision$
-:Date: $Date$
-:Copyright: This document has been placed in the public domain.
-
-
-`<commit-email.patch>`_ is a patch against ``commit-email.pl`` of
-Subversion 1.1.3. Note that the patch cannot be applied to newer
-versions of ``commit-email.pl``.
-
-It adds file names to the subject lines, which would otherwise only
-list directories. The Docutils Subversion repository currently uses
-this patched version of ``commit-email.pl`` to generate the check-in
-messages sent to the Docutils-checkins mailing list.
-
-The patch has been placed in the public domain.
diff --git a/sandbox/fwiemann/commit-email/commit-email.patch b/sandbox/fwiemann/commit-email/commit-email.patch
deleted file mode 100644
index ebc9a1ae4..000000000
--- a/sandbox/fwiemann/commit-email/commit-email.patch
+++ /dev/null
@@ -1,135 +0,0 @@
---- tools/hook-scripts/commit-email.pl 2004-06-14 22:29:22.000000000 +0200
-+++ tools/hook-scripts/commit-email.pl 2005-10-30 22:39:22.942246752 +0100
-@@ -222,32 +222,16 @@
- shift @svnlooklines;
- my @log = map { "$_\n" } @svnlooklines;
-
--# Figure out what directories have changed using svnlook.
--my @dirschanged = &read_from_process($svnlook, 'dirs-changed', $repos,
-- '-r', $rev);
--
--# Lose the trailing slash in the directory names if one exists, except
--# in the case of '/'.
--my $rootchanged = 0;
--for (my $i=0; $i<@dirschanged; ++$i)
-- {
-- if ($dirschanged[$i] eq '/')
-- {
-- $rootchanged = 1;
-- }
-- else
-- {
-- $dirschanged[$i] =~ s#^(.+)[/\\]$#$1#;
-- }
-- }
-
- # Figure out what files have changed using svnlook.
- @svnlooklines = &read_from_process($svnlook, 'changed', $repos, '-r', $rev);
-
- # Parse the changed nodes.
-+my @fileschanged;
- my @adds;
- my @dels;
- my @mods;
-+my $rootchanged = 0;
- foreach my $line (@svnlooklines)
- {
- my $path = '';
-@@ -261,6 +245,12 @@
- $path = $2;
- }
-
-+ push(@fileschanged, $path);
-+ if ($path eq '/')
-+ {
-+ $rootchanged = 1;
-+ }
-+
- if ($code eq 'A')
- {
- push(@adds, $path);
-@@ -288,11 +278,11 @@
- # there's no point in collapsing the directories, and only if more
- # than one directory was modified.
- my $commondir = '';
--if (!$rootchanged and @dirschanged > 1)
-+if (!$rootchanged and @fileschanged > 1)
- {
-- my $firstline = shift @dirschanged;
-+ my $firstline = shift @fileschanged;
- my @commonpieces = split('/', $firstline);
-- foreach my $line (@dirschanged)
-+ foreach my $line (@fileschanged)
- {
- my @pieces = split('/', $line);
- my $i = 0;
-@@ -306,28 +296,28 @@
- $i++;
- }
- }
-- unshift(@dirschanged, $firstline);
-+ unshift(@fileschanged, $firstline);
-
- if (@commonpieces)
- {
- $commondir = join('/', @commonpieces);
-- my @new_dirschanged;
-- foreach my $dir (@dirschanged)
-+ my @new_fileschanged;
-+ foreach my $file (@fileschanged)
- {
-- if ($dir eq $commondir)
-+ if ($file eq "$commondir/")
- {
-- $dir = '.';
-+ $file = '.';
- }
- else
- {
-- $dir =~ s#^$commondir/##;
-+ $file =~ s#^$commondir/##;
- }
-- push(@new_dirschanged, $dir);
-+ push(@new_fileschanged, $file);
- }
-- @dirschanged = @new_dirschanged;
-+ @fileschanged = @new_fileschanged;
- }
- }
--my $dirlist = join(' ', @dirschanged);
-+my $filelist = join(' ', @fileschanged);
-
- ######################################################################
- # Assembly of log message.
-@@ -367,7 +357,7 @@
- {
- my $match_re = $project->{match_re};
- my $match = 0;
-- foreach my $path (@dirschanged, @adds, @dels, @mods)
-+ foreach my $path (@adds, @dels, @mods)
- {
- if ($path =~ $match_re)
- {
-@@ -390,16 +380,20 @@
-
- if ($commondir ne '')
- {
-- $subject = "r$rev - in $commondir: $dirlist";
-+ $subject = "r$rev - in $commondir: $filelist";
- }
- else
- {
-- $subject = "r$rev - $dirlist";
-+ $subject = "r$rev - $filelist";
- }
- if ($subject_prefix =~ /\w/)
- {
- $subject = "$subject_prefix $subject";
- }
-+ if(length($subject) > 900)
-+ {
-+ $subject = substr($subject, 0, 896) . " ...";
-+ }
- my $mail_from = $author;
-
- if ($from_address =~ /\w/)
diff --git a/sandbox/fwiemann/fsfsbackup.sh b/sandbox/fwiemann/fsfsbackup.sh
deleted file mode 100755
index 32d472760..000000000
--- a/sandbox/fwiemann/fsfsbackup.sh
+++ /dev/null
@@ -1,90 +0,0 @@
-#!/bin/bash
-
-# Author: Felix Wiemann
-# Contact: Felix_Wiemann@ososo.de
-# Revision: $Revision$
-# Date: $Date$
-# Copyright: This file has been placed in the public domain.
-
-# Options:
-#
-# -f Do not print feedback.
-
-set -e
-
-trap "echo; echo Exiting with error.; trap - 0; exit 1" 0 1 2 3 15
-
-test "$1" == -f && printfeedback= || printfeedback=1
-
-function feedback() {
- test "$printfeedback" && echo "$@" || true
-}
-
-function do_backup() {
- # If any of the tests fails, the script terminates silently.
- feedback "Checking that all necessary variables are set."
- test -n "$BACKUPDIR"
- test -n "$HOST"
- test -n "$REMOTEDIR"
- if test ! -d "$BACKUPDIR"; then
- feedback "Creating backup directory $BACKUPDIR."
- mkdir --parents --verbose "$BACKUPDIR"
- fi
- if test ! -f "$BACKUPDIR/db/fs-type"; then
- feedback
- echo "$BACKUPDIR/db/fs-type not found."
- echo "Please fetch the first copy of the repository database yourself."
- echo "I only assist in doing incremental backups of repository databases."
- exit 1
- fi
- feedback "Checking that repository format is FSFS."
- test "`cat "$BACKUPDIR/db/fs-type"`" == fsfs
- feedback "Changing to database directory $BACKUPDIR/db."
- cd "$BACKUPDIR/db"
- feedback "Getting local current revision number."
- LOCALREVNUM="`cat current | sed 's/ .*//'`"
- feedback "Checking that current.new doesn't exist."
- if test -f current.new; then
- feedback
- echo "Make sure that no other instance of this script"
- echo "is running and delete the following file:"
- echo "$BACKUPDIR/db/current.new"
- exit 2
- fi
- feedback "Getting remote 'current' file."
- ssh "$HOST" "cat '$REMOTEDIR/db/current'" > current.new
- feedback "Getting remote current revision number."
- REMOTEREVNUM="`cat current.new | sed 's/ .*//'`"
- feedback "Checking that we got a response from the server."
- test -n "$REMOTEREVNUM"
- if ! test "$LOCALREVNUM" -le "$REMOTEREVNUM"; then
- feedback
- echo "ERROR: Local revision number ($LOCALREVNUM) greater"
- echo " than remote revision number ($REMOTEREVNUM)."
- echo "Wrong backup directory or changed repository?"
- exit 2
- fi
- if test "$LOCALREVNUM" -eq "$REMOTEREVNUM"; then
- feedback "No backup needed; at revision $LOCALREVNUM."
- feedback "Removing 'current.new'."
- rm current.new
- feedback "Done."
- return
- fi
- LOCALREVNUM="$[$LOCALREVNUM+1]"
- feedback "Backing up from revision $LOCALREVNUM to revision $REMOTEREVNUM."
- test "$printfeedback" && verbose=-v || verbose=
- ssh "$HOST" "
- set -e;
- cd $REMOTEDIR/db/;
- nice -n 10 tar cf - \`seq -f revs/%g $LOCALREVNUM $REMOTEREVNUM\` \`seq -f revprops/%g $LOCALREVNUM $REMOTEREVNUM\` | nice -n 10 bzip2 -c" \
- | tar $verbose -xjf -
- feedback "Renaming 'current.new' to 'current'."
- mv current.new current
- feedback "Done."
-}
-
-feedback 'Reading ~/.fsfsbackup.'
-source ~/.fsfsbackup
-feedback 'Finished.'
-trap - 0 1 2 3 15
diff --git a/sandbox/fwiemann/plugins/interface.py b/sandbox/fwiemann/plugins/interface.py
deleted file mode 100644
index 17e5d0a71..000000000
--- a/sandbox/fwiemann/plugins/interface.py
+++ /dev/null
@@ -1,256 +0,0 @@
-"""
-Designing the urgently-needed plugin support...
-
-This module doesn't work, it's just there for showing the design, from
-a plugin's point of view. (Kind of test-first. The required
-interfaces will be implemented in Docutils later.)
-
-Let's implement an extension for rendering keys:
-
-reST source:
- :key:`Ctrl+C`
-Node tree:
- <KeyNode>
- Ctrl
- +
- <KeyNode>
- C
-HTML rendering:
- <html><body><span style="border: 1px solid black;">Ctrl</span>+<span style="border: 1px solid black;">C</span></body></html>
-
-That isn't a particularly challenging task, but it's probably best to
-stick to something simple first. (Later we could try to make a plugin
-out of a math patch, but that will to require more code.)
-
-Things not (yet) covered here:
-
-* Adding a Component (this may require a generic frontend).
-* Adding a directive (will require more complicated code than for
- roles, because of arguments and options).
-* Extending the parser by modifying a parser instance. (Do we *want*
- to support that? It's powerful, but a little bit hackish.)
-* Adding a transform. (Do we need that?)
-* Writing a test case for an extension.
-"""
-
-
-class KeyNode(nodes.Inline, nodes.TextElement):
-
- """
- This is the node which stores the key texts (like "Ctrl" or "C").
- """
-
- def __init__(self, key):
- self += nodes.Text(key, key)
-
-
-def html_visit_keynode(visitor, node):
- """
- This is a visit_ method which looks like any normal Visitor
- method.
-
- It is referenced from the writer support class below.
- """
- if visitor.settings['key_html_tt']:
- # Now insert a string into the writer's data stream. There is
- # visitor.body.append(...) for the HTML visitor, but why not
- # just return the string? That's much easier. The visitor
- # should know where to put it.
- return visitor.starttag('tt',
- style='border: 1px solid black',
- CLASS='key')
- else:
- return visitor.starttag('span',
- style='border: 1px solid black',
- CLASS='key')
-
-def html_depart_keynode(visitor, node):
- """
- Now this is the depart method.
- """
- if visitor.settings['key_html_tt']:
- return '</tt>'
- else:
- return '</span>'
-
-
-class KeyNodeHTMLSupport(docutils.WriterExtension):
-
- """
- This class describes HTML writer handling for the KeyNode, i.e. it
- provides visit_ and depart_ methods. (By the way, is there any
- term for visit_/depart_ methods?)
- """
-
- extends = 'html4css1'
- """The writer this extension extends."""
-
- handlers = {'KeyNode': (html_visit_keynode, html_depart_keynode)}
- """
- Dictionary mapping node names to pairs of visit and departure
- functions.
- """
-
- name = 'DefaultKeyHTMLSupport'
- """
- Name of this extension.
-
- This is needed when there are several extensions proving support
- for the same node, because in this case the user would have to
- specify the name of the preferred extension (probably using an
- option).
-
- For convenience, maybe we shouldn't require setting a name
- attribute and have a default name of 'default' (or
- self.__class__?).
- """
-
- settings_spec = (('Render key buttons in <tt> tags in HTML.',
- ['--key-html-tt'],
- {'default': 0, 'action': 'store_true'}),
- ('Render key buttons in <span> tags in HTML.',
- ['--key-html-span'],
- {'dest': 'key_html_tt', 'action': 'store_false'},))
- """
- Sequence of settings.
- """
-
-
-class KeyNodeLaTeXSupport(docutils.WriterExtension):
-
- """Support for the LaTeX writer. See KeyNodeHTMLSupport."""
-
- extends = 'latex2e'
-
- handlers = {'KeyNode': ('\\fbox{', '}')}
- """
- Here we have strings instead of functions. They are simply
- inserted into the data stream; the visitor should know how to do
- this.
-
- This is shorter and simpler than using lambdas, e.g. ``(lambda:
- '\\fbox{', lambda: '}')``.
- """
-
- name = 'DefaultKeyLaTeXSupport'
-
-
-class KeyRole(docutils.ParserExtension):
-
- """
- This is the role implementation for the reST parser.
-
- It is only registered at the parser if the parser requests it.
-
- The reST parser, for example, issues a request when it encounters
- ".. require:: something". The request procedure might look like
- this:
-
- Let's say the reST parser encounters a ".. require:: key". Then
- it calls docutils.register_extension_by_id(self, 'key'). The
- register function determines that the first parameter (self) is a
- component instance of type Parser (so it only considers
- ParserExtensions) and that its name is 'restructuredtext' (so it
- only considers extensions whose `extends` attribute is
- 'restructuredtext').
-
- For all matching extensions, the register function then looks at
- the `id` attribute. If the second parameter ('key' in this
- example) matches `id`, the extension is registered at the
- component instance passed as first parameter.
- """
-
- extends = 'restructuredtext'
- """The component this extension extends."""
-
- id = 'key'
- """
- The id under which this extension is known.
-
- In this case, it's used for ".. require:: key" in reST.
-
- The presence of an `id` attribute means that the extension isn't
- loaded automatically but only on request. (Is that too much
- magic?)
- """
-
- type = 'role'
- """
- The type of this extension.
-
- Might also be 'directive', for example. This attribute is read by
- the reST parser.
- """
-
- # The rest of this class definition is specific to reST roles:
-
- role_name = 'key'
- """
- Name of this role.
-
- This means we can write :key:`Ctrl+C`.
-
- There is no i18n support yet, because using a dictionary like
- {'en': 'key'} seems a little bit too complex (since translations
- usually aren't necessary) and the current i18n system needs a
- redesign anyway.
- """
-
- raw = 1
- """
- If we pass pre-parsed contents to the role as proposed in
- <http://article.gmane.org/gmane.text.docutils.user/1727>, we need
- this ``raw`` attribute for the following purpose:
-
- The run() method wants to get a raw string, so we set raw to 1.
- (Backslashes aren't interpreted then, but that isn't important in
- the case of our key role.)
-
- If ``raw`` were 0, the run() method would get a list with one
- Text node. Backslashes would be interpreted, and if there
- were nested-inline-markup support, the list might contain any
- Inline elements.
-
- If the role handler processes the role contents itself as proposed
- in <http://article.gmane.org/gmane.text.docutils.user/1729>, we
- don't need the ``raw`` attribute.
- """
-
- def run(self, contents):
- """
- For the source text ":key:`Ctrl+C`", this method is called as
- keyrole_instance.run('Ctrl+C').
-
- lineno, inliner etc. aren't passed as parameters but they can
- be grabbed from instance variables if needed (like
- self.lineno). This avoids long useless copy'n'paste parameter
- lists.
-
- Return value is a tuple of a node list and a system-message
- list.
- """
-
- if (not contents or
- contents.startswith('+') or contents.endswith('+')
- or ' ' in contents):
- # Not a valid key combination.
- # Now we want to throw an error, but that isn't easy.
- # Theoretically, we could do:
- #msg = self.inliner.reporter.error(
- # 'Invalid key string: %s' % contents, lineno=self.lineno)
- #prb = self.inliner.problematic(contents, contents, msg)
- #return [prb], [msg]
- # But this causes a lot of redundancy, given that it's
- # such a common case. It would be better to have a
- # shortcut like this instead:
- raise self.parser.RoleError('Invalid key string')
- # which does the same as the three lines above.
-
- # Now comes our highly sophisticated key combination parsing
- # algorithm.
- keys = contents.split('+')
- nodes = [KeyNode(keys[0])]
- for i in keys[1:]:
- nodes.append(nodes.Text('+'))
- nodes.append(KeyNode(i))
- return [nodes], []
diff --git a/sandbox/fwiemann/release.sh b/sandbox/fwiemann/release.sh
deleted file mode 100755
index f24cbd5bd..000000000
--- a/sandbox/fwiemann/release.sh
+++ /dev/null
@@ -1,490 +0,0 @@
-#!/bin/bash
-
-# Author: Felix Wiemann
-# Contact: Felix_Wiemann@ososo.de
-# Revision: $Revision$
-# Date: $Date$
-# Copyright: This script has been placed in the public domain.
-
-set -e
-
-function print_command()
-{
- # Print "$@", quoting parameters containing spaces.
- echo -n $
- for param in "$@"; do
- echo "$param" | grep -Fq ' ' && echo -n " '$param'" || echo -n " $param"
- done
-}
-
-function run()
-{
- # Print and run "$@".
- print_command "$@"
- echo
- "$@"
-}
-
-function confirm()
-{
- # Print, let the user confirm and run "$@".
- echo 'Press enter to run (or enter anything to skip):'
- print_command "$@"
- read
- test "$REPLY" && echo Skipped. || "$@"
-}
-
-function svn_up()
-{
- if test $svn == svk; then
- confirm svk sync "$depot"
- fi
- confirm $svn up
-}
-
-function checkin()
-{
- # Parameters: log_message, file, file, file ...
- log_message="$1"
- shift
- confirm $svn diff "$@"
- confirm $svn ci -m "$log_prefix $log_message" "$@"
-}
-
-function set_ver()
-{
- # Parameters: old_version new_version
- shopt -s extglob
- echo Determining list of files to be changed...
- files="docutils/__init__.py setup.py `$svn ls test/functional/expected/ | sed 's|^|test/functional/expected/|'`"
- echo "Now I'll change the version number to $2 in the following files:"
- echo $files
- echo
- echo 'Press enter to proceed (or enter anything to skip)...'
- read
- if [ ! "$REPLY" ]; then
- echo 'Modifying files with ed...'
- old_ver_regex="`echo "$1" | sed 's/\./\\\\./g'`"
- # "ed" returns an error code if there has been no substitution, so
- # we temporarily deactivate exit-on-error.
- set +e
- for F in $files; do
- (echo ",s/$old_ver_regex/$2/g"; echo 'wq') | ed "$F"
- done
- set -e
- fi
- echo
- checkin "set version number to $2" $files
-}
-
-function usage()
-{
- echo 'Usage:'
- echo
- echo ' release.sh new_version svn_version[:branch_version] [stage]'
- echo
- echo 'The following things will be done:'
- echo
- echo '* Change version number to new_version. (stage 1)'
- echo '* SVN-export, test, and release Docutils version new_version. (stage 2)'
- echo '* Change version number to svn_version. (stage 3)'
- echo
- echo 'If stage is supplied (1, 2 or 3), only the specified stage will'
- echo 'be executed. Otherwise, it defaults to executing all stages.'
- echo
- echo 'Before doing dangerous things, you will be asked to press enter.'
- echo
- echo 'A maintenance branch called docutils-new_version will be created'
- echo 'if branch_version is given. The version number inside the'
- echo 'maintenance branch will be set to branch_version.'
- exit 1
-}
-
-function initialize()
-{
- if [ "$#" -lt 2 ]; then
- usage
- fi
- echo 'Initializing...'
- python_versions='2.1 2.2 2.3 2.4'
- for py_ver in $python_versions; do
- echo -n "Checking for Python $py_ver (python$py_ver)... "
- if ! echo 'print "OK"' | python$py_ver; then
- echo "Python $py_ver (python$py_ver) not found."
- echo Aborting.
- exit 1
- fi
- done
- echo -n 'Clearing $PYTHONPATH... '
- export PYTHONPATH=
- echo 'done'
- echo -n 'Checking whether we are in a working copy... '
- if [ -f HISTORY.txt ]; then
- echo yes
- else
- echo "no (HISTORY.txt doesn't exist)"
- echo 'Aborting.'
- echo 'Please cd to a working copy before running this script.'
- exit 1
- fi
- echo -n 'Subversion binary to use: '
- if [ -d .svn ]; then
- svn=svn
- else
- svn=svk
- fi
- echo $svn
- working_copy="`pwd -P`"
- echo "Working copy: $working_copy"
- if test $svn = svk; then
- depot_path="`svk info . | grep ^Depot\ Path: | sed 's/Depot Path: //'`"
- depot="`echo "$depot_path" | sed 's|\(//[^/]\+/[^/]\+\).*|\1|'`"
- echo "SVK depot: $depot"
- mirrored_from="`svk info . | grep ^Mirrored\ From: | sed 's/Mirrored From: //;s/, Rev\. .*//'`"
- svnurl="$mirrored_from`echo "$depot_path" | sed 's|//[^/]\+/[^/]\+||'`"
- else
- svnurl="`$svn info . | grep ^URL: | sed 's/URL: //'`"
- fi
- if test -z "$svnurl"; then
- echo 'Unable to detect Subversion URL. Aborting.'
- exit 1
- fi
- echo "Subversion URL: $svnurl"
- if ! echo "$svnurl" | grep -q 'branches\|trunk'; then
- echo 'Subversion URL contains neither "branches" nor "trunk".'
- echo 'Aborting.'
- exit 1
- fi
- svnroot="`echo "$svnurl" | sed 's/\/\(branches\|trunk\).*//'`"
- echo "Subversion root URL: $svnroot"
- if test "$svnurl" = "$svnroot"; then
- echo 'Error: Subversion URL and Subversion root URL are the same.'
- exit 1
- fi
- echo -n 'Detecting current Docutils version... '
- old_ver="`python -c 'import docutils; print docutils.__version__'`"
- echo "$old_ver"
- new_ver="$1"
- # log_prefix is for SVN logs.
- log_prefix="Release $new_ver:"
- echo "New version number (for releasing): $new_ver"
- svn_ver="$2"
- if echo "$svn_ver" | grep -q :; then
- # Split at colon: svn_ver:branch_ver
- branch_ver="${svn_ver#*:}"
- svn_ver="${svn_ver%:*}"
- else
- branch_ver=
- fi
- echo "New Subversion version number (after releasing): $svn_ver"
- echo -n 'Create maintenance branch: '
- if test "$branch_ver"; then
- echo yes
- echo "New version number on maintenance branch: $branch_ver"
- else
- echo no
- fi
- if test "$branch_ver"; then
- echo -n 'Checking that we have a full checkout... '
- if echo "$working_copy" | grep -q 'branches\|trunk'; then
- echo OK
- else
- echo 'no'
- echo 'Working copy path contains neither "branches" nor "trunk".'
- echo 'You need a full checkout in order to branch.'
- echo 'Aborting.'
- exit 1
- fi
- wcroot="`echo "$working_copy" | sed 's/\/\(branches\|trunk\).*//'`"
- echo "Working copy root: $wcroot"
- fi
- tarball=docutils-"$new_ver".tar.gz
- echo "Tarball name: $tarball"
- echo 'Initialization completed.'
- echo
-}
-
-function test_tarball()
-{
- # Assume we have the tarball in the current directory.
- # Pass test number as first parameter.
- echo 'Testing the release tarball.'
- run mkdir tarball_test/
- run cd tarball_test/
- confirm tar xzvf "../$tarball"
- echo
- run cd docutils-"$new_ver"
- echo 'Installing the distribution.'
- # Extra files, with leading comma.
- extras="`cd extras; for extrafile in *.py; do echo -n ",$extrafile{,c,o}"; done`"
- confirm su -c '
- for py_ver in '"$python_versions"'; do
- echo "Deleting and installing Docutils and its test suite on Python $py_ver."
- echo "Press enter."
- read
- site_packages="/usr/local/lib/python$py_ver/site-packages"
- if test ! -d "$site_packages"; then
- site_packages="/usr/lib/python$py_ver/site-packages"
- fi
- if test ! -d "$site_packages"; then
- echo "Error: \"$site_packages\" does not exist."
- exit 1
- fi
- if -e "$site_packages/test"; then
- echo "Error: \"$site_packages/test\" exists."
- exit 1
- fi
- rm -rfv /usr/{local,}lib/python$py_ver/site-packages/{docutils'"$extras"'}
- python$py_ver setup.py install
- echo
- cp -rv test "$site_packages/"
- echo "Press enter to continue."
- read
- done'
- echo 'Running the test suite with all Python versions.'
- echo 'Press enter (or enter anything to skip):'
- read
- if [ ! "$REPLY" ]; then
- for py_ver in $python_versions; do
- site_packages="/usr/local/lib/python$py_ver/site-packages"
- if test ! -d "$site_packages"; then
- site_packages="/usr/lib/python$py_ver/site-packages"
- fi
- if test ! -d "$site_packages"; then
- echo "Error: \"$site_packages\" does not exist."
- exit 1
- fi
- run python$py_ver -u "$site_packages/test/alltests.py"
- run find -name \*.pyc -exec rm {} \;
- done
- fi
- run cd ..
- echo "Cleaning up..."
- run rm -rf tarball_test
- confirm su -c '
- for py_ver in '"$python_versions"'; do
- rm -rfv /usr{/local,}/lib/python$py_ver/site-packages/test
- done'
- echo
-}
-
-function upload_tarball()
-{
- # Assume we have the tarball in the working area.
- run cd "$working_area"
- # You may need to adjust the command line for clients other than tnftp.
- (echo 'bin'; echo 'cd /incoming'; echo "put $tarball") | \
- ftp ftp://anonymous:none@upload.sourceforge.net/
- echo 'Upload completed.'
-}
-
-function upload_htdocs()
-{
- # Assume we have the tarball in the working area.
- run cd "$working_area"
- echo "Upload htdocs for $new_ver"
- run mkdir htdocs
- run cd htdocs
- confirm tar xzvf "../$tarball"
- run cd docutils-"$new_ver"/tools/
- confirm ./buildhtml.py ..
- run cd ..
- echo '$ find -name test -type d -prune -o -name \*.css -print0 \
- -o -name \*.html -print0 -o -name \*.txt -print0 \
- | tar -cjvf docutils-docs.tar.bz2 -T - --null'
- find -name test -type d -prune -o -name \*.css -print0 \
- -o -name \*.html -print0 -o -name \*.txt -print0 \
- | tar -cjvf docutils-docs.tar.bz2 -T - --null
- echo 'Upload the tarball to your home directory on SF.net...'
- confirm scp docutils-docs.tar.bz2 shell.sourceforge.net:
- echo
- echo 'Unpack the tarball on SF.net...'
- echo 'Press enter (or enter anything to skip).'
- read
- if [ ! "$REPLY" ]; then
- ssh shell.sourceforge.net<<-EOF
- set -x
- umask 002
- cd /home/groups/d/do/docutils/htdocs/
- mkdir -m g+rwxs $new_ver
- cd $new_ver
- tar -xjvf ~/docutils-docs.tar.bz2
- rm ~/docutils-docs.tar.bz2
-EOF
- fi
-}
-
-function create_maintenance_branch()
-{
- echo 'Creating maintenance branch.'
- branch_name="docutils-$new_ver"
- echo "Branch name: $branch_name"
- branch_url="$svnroot/branches/$branch_name"
- echo "Branch URL: $branch_url"
- confirm svn cp "$svnurl" "$branch_url" -m \
- "$log_prefix creating maintenance branch for version $new_ver"
- cd "$wcroot"
- svn_up
- cd branches/"$branch_name"
- set_ver "$new_ver" "$branch_ver"
-}
-
-function run_stage()
-{
- if [ ! "$1" ]; then
- run_stage 1
- echo
- run_stage 2
- echo
- run_stage 3
- else
- echo "Press enter to run stage $1 (or enter anything to skip this stage)."
- read
- if [ ! "$REPLY" ]; then
- cd "$working_copy"
- if [ "$1" == 1 ]; then
- stage_1
- elif [ "$1" == 2 ]; then
- stage_2
- elif [ "$1" == 3 ]; then
- stage_3
- else
- echo 'Invalid stage.'
- echo
- usage
- fi
- echo
- echo "Stage $1 completed."
- else
- echo "Skipped stage $1."
- fi
- fi
-}
-
-function stage_1()
-{
- svn_up
- echo
- # update __version_details__ string
- (echo ",s/^__version_details__ = .*\$/__version_details__ = 'release'/";
- echo wq) | ed docutils/__init__.py 2> /dev/null
- set_ver "$old_ver" "$new_ver"
- echo
- history_files='HISTORY.txt RELEASE-NOTES.txt'
- echo "Now updating the following files: $history_files"
- old_string="Changes Since [0-9.]+"
- new_string="Release $new_ver (`date --utc --iso-8601`)"
- echo 'Press enter to replace "'"$old_string"'" with "'"$new_string"\",
- echo 'or enter anything to skip.'
- read
- test "$REPLY" || python -c "for filename in '$history_files'.split():
- import re
- h = file(filename).read()
- h = re.sub('$old_string\\n=+', '$new_string\\n' + '=' * len('$new_string'), h, count=1)
- file(filename, 'w').write(h)"
- checkin 'closed "Changes Since ..." section' $history_files
-}
-
-function stage_2()
-{
- echo 'Creating working area...'
- working_area="`echo ~/tmp/docutils-release.$$`"
- run mkdir -p "$working_area"
- echo
- echo 'Getting a fresh export.'
- echo 'Press enter to proceed (or enter anything to skip)...'
- read
- if [ ! "$REPLY" ]; then
- run cd "$working_area"
- confirm svn export "$svnurl"
- echo
- echo 'Building the release tarball.'
- run cd docutils
- confirm ./setup.py sdist
- run cd ..
- echo 'Tarball built.'
- run cp docutils/dist/"$tarball" .
- confirm test_tarball
- echo "Testing documentation and uploading htdocs of version $new_ver..."
- confirm upload_htdocs
- echo "Tagging current revision..."
- confirm $svn cp "${svnurl%/trunk*}/trunk/" "${svnurl%/trunk*}/tags/docutils-$new_ver/" -m "$log_prefix tagging released revision"
- echo "Uploading $tarball to SF.net."
- confirm upload_tarball
- echo 'Now go to https://sourceforge.net/project/admin/editpackages.php?group_id=38414'
- echo 'and follow the instructions at'
- echo 'http://docutils.sf.net/docs/dev/release.html#file-release-system'
- echo
- echo 'Then press enter.'
- read
- fi
- run cd $working_area
- echo 'Downloading the tarball to verify its integrity.'
- while true; do
- confirm wget http://osdn.dl.sourceforge.net/sourceforge/docutils/"$tarball"
- echo 'Was the download successful?'
- echo 'If yes, press enter to continue, otherwise enter anything to repeat'
- echo '(it is possible that the file will show up in a few minutes).'
- read
- test "$REPLY" || break
- done
- confirm test_tarball
- echo 'Registering at PyPI...'
- echo 'Press enter to proceed (or enter anything to skip)...'
- read
- if [ ! "$REPLY" ]; then
- echo "Unpacking tarball..."
- ls -l
- pwd
- run tar xzvf "$tarball"
- run cd docutils-"$new_ver"
- confirm ./setup.py register
- fi
-}
-
-function stage_3()
-{
- svn_up
- echo
- # update __version_details__ string
- (echo ",s/^__version_details__ = .*\$/__version_details__ = 'repository'/";
- echo wq) | ed docutils/__init__.py 2> /dev/null
- checkin 'set __version_details__ to "repository"'
- echo
- history_files='HISTORY.txt RELEASE-NOTES.txt'
- echo "Now updating the following files: $history_files"
- add_string="Changes Since $new_ver"
- before="Release "
- echo 'Press enter to add "'"$add_string"'" section,'
- echo 'or enter anything to skip.'
- read
- test "$REPLY" || python -c "for filename in '$history_files'.split():
- import re
- h = file(filename).read()
- h = re.sub('$before', '$add_string\\n' + '=' * len('$add_string') +
- '\\n\\n\\n$before', h, count=1)
- file(filename, 'w').write(h)"
- checkin "added empty \"Changes Since $new_ver\" section" $history_files
- echo
- if test "$branch_ver"; then
- create_maintenance_branch
- cd "$working_copy"
- fi
- set_ver "$new_ver" "$svn_ver"
- echo
- echo 'Please update the web page now (web/index.txt).'
- echo "Press enter when you're done."
- read
- echo 'Running docutils-update on the server...'
- echo 'This may take some time.'
- confirm ssh shell.berlios.de docutils-update
-}
-
-initialize "$@"
-run_stage "$3"
-echo
-echo 'Finished.'
-
-# Local Variables:
-# indent-tabs-mode: nil
-# End:
diff --git a/sandbox/fwiemann/users.txt b/sandbox/fwiemann/users.txt
deleted file mode 100644
index d6daa8b13..000000000
--- a/sandbox/fwiemann/users.txt
+++ /dev/null
@@ -1,70 +0,0 @@
-# User names merged from SourceForge and BerliOS as of
-# $Date$.
-aahz
-agurtovoy
-aisaac0
-ajung
-akuchling
-ax-
-axk
-bbum
-bjoernp
-blais
-cben
-chodorowski
-cliechti
-daddygravity
-david_abrahams
-david_ascher
-dkuhlman
-docutilsupdate
-dreamcatcher
-ebellot
-edloper
-fdrake
-felixwiemann
-fermigier
-fffish
-goodger
-grubert
-gschwant
-gtk
-holdenweb
-i_am_the_user
-ianbicking
-injektilo
-jaffray
-jensj
-jfmeinel
-jhsh2
-ksato
-kvaml
-lalo
-lcreighton
-lele
-mezis
-mly
-mmgilbe
-mnodine
-mwh
-orutherfurd
-pefu
-pobrien
-reggie
-richard
-richieadler
-rnd0110
-sconce
-sdeibel
-sfcben
-smerten
-smurf
-sunib
-syt
-tav
-tibs
-tracyshaun
-ueli
-wilk
-yole
-zemiak
diff --git a/sandbox/fwiemann/xhtml2rest/README.txt b/sandbox/fwiemann/xhtml2rest/README.txt
deleted file mode 100644
index a5f66a89c..000000000
--- a/sandbox/fwiemann/xhtml2rest/README.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-This is xhtml2rest.
-
-It's a stop-gap solution for converting XHTML documents to
-reStructuredText.
-
-Please find the documentation inline at the beginning of the source
-file.
-
-The author is Antonios Christofides. It's in my (Felix Wiemann's)
-sandbox because he asked me to take care of it. So please direct any
-patches to Felix.Wiemann@ososo.de.
-
-Have fun!
-
-Felix Wiemann <Felix.Wiemann@ososo.de>
diff --git a/sandbox/fwiemann/xhtml2rest/xhtml2rest.py b/sandbox/fwiemann/xhtml2rest/xhtml2rest.py
deleted file mode 100755
index 8c6b366db..000000000
--- a/sandbox/fwiemann/xhtml2rest/xhtml2rest.py
+++ /dev/null
@@ -1,551 +0,0 @@
-#!/usr/bin/python
-"""
-NAME
-====
-
-xhtml2rest - Convert xhtml to reStructuredText
-
-SYNOPSIS
-========
-
-xhtml2rest *xhtmlfile* > *restfile*
-
-DESCRIPTION
-===========
-
-``xhtml2rest``, which, far from being a decent and complete program, is
-only something to begin with, hopefully processes the given UTF-8
-xhtml file and produces reStructuredText "source code" in the standard
-output. If your input is html and/or not in UTF-8, you can convert it
-to UTF-8 xhtml using ``iconv`` and ``tidy``:
-
- iconv -f *source_encoding* -t utf-8 *source_html* > *html_utf8*
-
- tidy -utf8 -asxml -o *xhtmlfile* *html_utf8*
-
- xhtml2rest *xhtmlfile* > *restfile*
-
-Interestingly, since reStructuredText is not simple markup, but has
-very strict rules with the intention that the source is perfectly
-readable, it turns out that converting html to reStructuredText is
-actually *rendering*. ``xhtml2rest`` is a small rendering engine. Since
-I had no time to study how existing rendering engines work, I had to
-reinvent the wheel. So although the code is clean (I actually wrote it
-twice), I doubt that the core logic is adequate for future extensions.
-But it's better than nothing. There is some documentation in the code,
-but feel free to email me if you need more explanations.
-
-LIMITATIONS
-===========
-
-I created ``xhtml2rest`` for a very specific job. It does that job
-correctly, but for your web page it might not work. It should not be
-very hard, however, either to improve the code, or to determine what
-it is in your web page that confuses ``xhtml2rest`` and remove it.
-
-Other than that, there are the following limitations:
-
-* No indented tables
-
-* No multi-col or -row spans in tables
-
-* No support for \<br>
-
-* Not tested in nested tables (check http://www.w3m.org/story.html)
-
-* \<th> support is quick and dirty
-
-* If the same anchor text is met twice, the anchor is ignored
-
-* No indented \<pre> elements (but I'm not sure the HTML standard
- allows them)
-
-* Images are ignored
-
-* The word HARDWIRED in the code indicates a hardwired hack which is
- specific to the job I wanted ``xhtml2rest`` to do.
-
-META
-====
-
-``xhtml2rest`` was created by Antonios Christofides,
-anthony@itia.ntua.gr, May-June 2005.
-
-Revision: $Revision$
-
-The code and this text is hereby placed in the public domain.
-"""
-
-import xml.dom.minidom
-import re
-import sys
-import textwrap
-import math
-import UserList
-import warnings
-import codecs
-
-###############################################################################
-# Global variables. I know. I'm terribly sorry. Please get rid of them.
-
-# 'unindent' is used by list items. A li list item is always indented, but its
-# first line is "unindented" and contains the number or bullet. However, it was
-# difficult for the li node to tell its #text contents (which may be deeply
-# nested) to use that. So it just places the number or bullet, which must be 4
-# characters, like " 1. ", in "unindent". The first text to be rendered uses
-# the unindent and then sets it to empty again.
-
-unindent = ''
-hyperlinks = {} # text-target pairs found in "a href" elements
-###############################################################################
-
-class Ditem:
- """A document item; usually a node, but can be a block of text
- resulting from processing adjacent inline items. If it is a node,
- it is usually the BlockDitem subclass; if it is text, it is
- normally a plain Ditem."""
- def __init__(self, text):
- self.text = text # Contained text (empty for BlockDitem)
- self.type = '' # tag for block node, empty for inline
- self.indentlevel = 0 # 0 - unindented; 1 - indented; etc.
- def __repr__(self):
- return self.__class__.__name__+'("""'+self.text+'""")'
- def propagate_indents(self):
- "Propagates indent level recursively to children"
- pass
- def maxwidth(self):
- "Width it will occupy if allowed to render on infinite width"
- self.remove_white_space()
- return len(self.text) + 4*self.indentlevel
- def minwidth(self):
- "Width it will occupy if wrapped as much as possible"
- wordlens = [len(x) for x in self.text.split()]
- if wordlens: return max(wordlens) + 4*self.indentlevel
- else: return 0
- def format(self, width):
- """Returns contents formatted so as not to exceed specified
- width, if possible"""
- global unindent
- if(self.type=='pre'): raise Exception, "What are we doing here?"
- self.remove_white_space()
- # Quick hack to fix a problem. Do we begin with '* '?
- while len(self.text)>=2 and self.text[1]==' ' and self.text[0] in '*-':
- # It may be mistaken for a bullet list. Strip it.
- self.text = self.text[2:]
- if width < self.minwidth(): width = self.minwidth()
- # The textwrap module has the nasty habit of breaking at hyphens. So
- # we'll do a nasty hack: find a character that does not exist in the
- # text, replace all hyphens with that character, ok, you get the point.
- hyphensurrogate = ''
- for c in '!@#$%^&*~':
- if self.text.find(c)<0:
- hyphensurrogate = c
- break
- if not hyphensurrogate: raise Exception, "Houston we have a problem"
- text = self.text.replace('-', hyphensurrogate)
- wrapper = textwrap.TextWrapper(
- initial_indent=((4*self.indentlevel)-len(unindent))*' '+unindent,
- subsequent_indent=4*self.indentlevel*' ',
- width=width, break_long_words = False)
- unindent = ''
- text = wrapper.fill(text)
- text = text.replace(hyphensurrogate, '-')
- return text
- def empty(self):
- "Returns true if contains nothing"
- return not self.text
- def remove_white_space(self):
- "Removes extra white space"
- self.text = re.sub('\s+', ' ', self.text).strip()
- def canmerge(self):
- "Tells whether it's possible to merge this Ditem with adjacent ones"
- return True
- def merge(self, aditem):
- """If possible, merges aditem, which should be an adjacent Ditem that
- comes after this one."""
- if not self.canmerge() or not aditem.canmerge(): return False
- if len(self.text)>0 and self.text[-1] == '_' and len(aditem.text)>0 \
- and aditem.text[0] not in """ \n\t:.,!=/|;"'?<>[]{}()""":
- # Leave space after link if not followed by punctuation
- self.text = self.text + ' ' + aditem.text
- else:
- self.text = self.text + aditem.text
- return True
-
-class BlockDitem(Ditem):
- "A Ditem which contains other Ditems"
- def __init__(self, type):
- Ditem.__init__(self, '')
- self.type = type
- self.children = [] # Contained Ditems
- def __repr__(self):
- return self.__class__.__name__+'("'+self.type+'"); children = '+repr(self.children)
- def maxwidth(self):
- childmaxwidths = [x.maxwidth() for x in self.children]
- return childmaxwidths and max(childmaxwidths) or 0
- def minwidth(self):
- childminwidths = [x.minwidth() for x in self.children]
- return childminwidths and max(childminwidths) or 0
- def propagate_indents(self):
- for x in self.children:
- x.indentlevel = self.indentlevel
- x.propagate_indents()
- def format(self, width):
- if width < self.minwidth(): width = self.minwidth()
- results = [x.format(width) for x in self.children]
- results = [x for x in results if x]
- return "\n\n".join(results)
- def empty(self):
- return not (self.children)
- def canmerge(self):
- return False
-
-class PreDitem(Ditem):
- "A Ditem representing a literal block"
- def maxwidth(self):
- return max([len(x) for x in self.text.split('\n')])
- def minwidth(self):
- return self.maxwidth() # Literal block; width's given
- def remove_white_space(self):
- pass
- def format(self, width):
- result = '::\n\n'
- for x in self.text.split('\n'):
- result = result + ' ' + x + '\n'
- result = result + '..\n\n'
- return result
- def canmerge(self):
- return False
-
-class HeadingDitem(BlockDitem):
- "A Ditem representing an h1, h2, ..., h9"
- def __init__(self, type):
- BlockDitem.__init__(self, type)
- def minwidth(self):
- return self.maxwidth() # Headings don't wrap
- def format(self, width):
- assert(len(self.children)==1)
- text = self.children[0].format(32767)
- level = eval(self.type[1])
- underliner = "=-`'.~*+^"[level-1]
- return text + '\n' + len(text)*underliner
-
-class BlockQuoteDitem(BlockDitem):
- "A Ditem representing a blockquote"
- def __init__(self, type):
- BlockDitem.__init__(self, type)
- def propagate_indents(self):
- self.indentlevel = self.indentlevel + 1
- BlockDitem.propagate_indents(self)
-
-class ListDitem(BlockDitem):
- "A Ditem representing an ol, ul, or dl"
- def __init__(self, type):
- BlockDitem.__init__(self, type)
- def format(self, width):
- # First pass the list type and order to the children
- order = 1
- for x in self.children:
- if isinstance(x, ListItemDitem):
- x.listtype = self.type
- x.order = order
- order = order+1
- # And then process normally
- return BlockDitem.format(self, width)
-
-class ListItemDitem(BlockDitem):
- "A Ditem representing a li, dt, or dd"
- def __init__(self, type):
- BlockDitem.__init__(self, type)
- self.listtype = None
- self.order = 0
- def minwidth(self):
- if self.type == 'dt': return self.maxwidth() # Don't wrap dt
- else: return BlockDitem.minwidth(self)
- def propagate_indents(self):
- if self.type in ('li', 'ol', 'dd'):
- self.indentlevel = self.indentlevel + 1
- BlockDitem.propagate_indents(self)
- def format(self, width):
- global unindent
- if self.type == 'li' and self.listtype == 'ol':
- unindent = ('%d. ' % (self.order)).ljust(4)
- elif self.type == 'li' and self.listtype == 'ul':
- unindent = '* '
- return BlockDitem.format(self, width)
-
-class RenderedColumn:
- "Width information about a column being rendered"
- def __init__(self, minwidth, maxwidth):
- self.minwidth = minwidth
- self.maxwidth = maxwidth
- self.curwidth = maxwidth
- self.fixedwidth = 0
- def logwidth(self):
- if self.maxwidth==0: return 0
- else: return math.log(self.maxwidth)
- def update(self, minwidth, maxwidth):
- "Replaces minwidth/maxwidth if greater"
- self.minwidth = minwidth>self.minwidth and minwidth or self.minwidth
- self.maxwidth = maxwidth>self.maxwidth and maxwidth or self.maxwidth
- self.curwidth = self.maxwidth
-
-class RenderedColumns(UserList.UserList):
- "A list of RenderedColumn"
- def __init__(self, alist):
- self.data = alist
- def totalWidth(self):
- "Returns total table width"
- return reduce(lambda x,y: x+y, [z.curwidth for z in self.data]) \
- + len(self.data) + 1
- def sumLogWidth(self):
- "Returns sum of logwidth for nonfixed columns"
- return reduce(lambda x,y: x+y,
- [x.logwidth()*(1-x.fixedwidth) for x in self.data])
- def distributeWidthDifference(self, width):
- "Step 4 of w3m table rendering algorithm"
- # Note: The use of math.ceil below is because I'd rather have a
- # suboptimal width (a few characters less than requested width) rather
- # than go find what to do with rounding.
- w = self.totalWidth() - width
- assert(w>0)
- repeat_distribution = 1
- while repeat_distribution:
- repeat_distribution = 0
- for x in self.data:
- if x.fixedwidth: continue
- if x.curwidth - math.ceil(w*x.logwidth()/self.sumLogWidth()) < \
- x.minwidth:
- x.curwidth = x.minwidth
- x.fixedwidth = 1
- w = self.totalWidth() - width
- repeat_distribution=1
- break
- # Now that the we finished finding which columns need to be fixed to
- # their minimum width, perform the distribution once again, without
- # checking, and actually change remaining column widths
- for x in self.data:
- if x.fixedwidth: continue
- x.curwidth = x.curwidth - math.ceil(w*x.logwidth()/self.sumLogWidth())
-
-def tablehrule(colwidths, rule='-'):
- "Returns a horizontal table separator for given column widths"
- result = '+'
- for x in colwidths:
- result = result + rule * x + '+'
- return result
-
-class TableDitem(BlockDitem):
- def __init__(self, type):
- BlockDitem.__init__(self, type)
- def format(self, width):
- # Uses table rendering algorithm of w3m
- # (http://www.w3m.org/story.html), but ignoring width attribute
- # Step 1
- columns = RenderedColumns([RenderedColumn(x.minwidth(),
- max(x.maxwidth(), 1) # A column can't be smaller than 1 character
- ) for x in self.children[0].children])
- for x in self.children:
- for i in range(len(columns)):
- if (len(x.children)<=i): continue # Skip empty columns
- columns[i].update(x.children[i].minwidth(), x.children[i].maxwidth())
- # Step 2 (width attribute) ignored
- # Step 3 (already done - list was created with maxwidth)
- # Step 4
- if columns.totalWidth() > width: columns.distributeWidthDifference(width)
- # OK, column widths are now calculated
- colwidths = [int(x.curwidth) for x in columns]
- result = tablehrule(colwidths) + '\n'
- usedheadbodysep = False
- for tr in self.children:
- result = result + tr.format(colwidths)
- rule = '-'
- if not usedheadbodysep and tr.children[0].type == 'th' \
- and tr!=self.children[-1]:
- rule = '='
- usedheadbodysep = True
- result = result + tablehrule(colwidths, rule) + '\n'
- return result
-
-class TrDitem(BlockDitem):
- def __init__(self, type):
- BlockDitem.__init__(self, type)
- def maxwidth(self):
- return reduce(lambda x,y: x+y,
- [x.maxwidth() for x in self.children]) + len(self.children) + 1
- def minwidth(self):
- return reduce(lambda x,y: x+y,
- [x.minwidth() for x in self.children]) + len(self.children) + 1
- def format(self, colwidths):
- columns = [] # List of lists of lines
- maxlinecount = 0 # Num of lines in vertically largest column
- for i in range(len(colwidths)):
- if len(self.children)<=i: lines = [ '' ]
- else: lines = self.children[i].format(colwidths[i]).split('\n')
- lines = [x + ' ' * (colwidths[i]-len(x)) for x in lines] # Pad to col len
- maxlinecount = max(maxlinecount, len(lines))
- columns.append(lines)
- # Pad vertically
- for i in range(len(columns)):
- for j in range(maxlinecount-len(columns[i])):
- columns[i].append(' ' * colwidths[i])
- result = ''
- # Add vertical separators
- for i in range(maxlinecount):
- result = result + '|'
- for j in range(len(columns)):
- result = result + columns[j][i] + '|'
- result = result + '\n'
- return result
-
-def handleNodeList(nodelist):
- "Processes given nodes; merges them if possible; returns ditem list"
- ditems = []
- curditem = Ditem('')
- for node in nodelist:
- aditem = handleNode(node)
- if curditem.merge(aditem): continue
- ditems.append(curditem)
- curditem = aditem
- if not curditem.empty(): ditems.append(curditem)
- return ditems
-
-def handleNode(node):
- if node.nodeType == node.TEXT_NODE:
- return handleText(node)
- elif node.nodeName=='a':
- return handleAnchor(node)
- elif re.match('h\d', node.nodeName):
- return handleHeading(node)
- elif node.nodeName=='div' and node.getAttribute('class')=='cit': # HARDWIRED
- return handleBlockQuote(node)
- elif node.nodeName in ('body', 'div', 'p', 'td', 'th'):
- return handleGenericBlock(node)
- elif node.nodeName in ('em', 'i'):
- return handleEmphasis(node)
- elif node.nodeName in ('strong', 'b'):
- return handleStrong(node)
- elif node.nodeName in ('ol', 'ul', 'dl'):
- return handleList(node)
- elif node.nodeName in ('li', 'dd', 'dt'):
- return handleListItem(node)
- elif node.nodeName in ('table'):
- return handleTable(node)
- elif node.nodeName in ('tr'):
- return handleTr(node)
- elif node.nodeName in ('pre'):
- return handlePre(node)
- elif node.hasChildNodes():
- contents = handleNodeList(node.childNodes)
- if len(contents) == 1: return contents[0]
- if len(contents) == 0: return Ditem('')
- result = BlockDitem(node.nodeName)
- result.children = contents
- return result
- return Ditem('')
-
-def processChildren(node):
- if node.hasChildNodes():
- return handleNodeList(node.childNodes)
- else:
- return ()
-
-def mergeChildren(node):
- contents = processChildren(node)
- if len(contents)>1: raise Exception('Unexpected block elements')
- if contents: return contents[0]
- else: return Ditem('')
-
-def handleText(node):
- return Ditem(node.data)
-
-def handleAnchor(node):
- result = mergeChildren(node)
- result.type = node.nodeName
- result.text = result.text.strip()
- if result.text == '': return result
- target = node.getAttribute('href').strip()
- if target=="" or target[0]=='#': return result # Ignore intrnl links
- result.text = re.sub('\s+', ' ', result.text)
- key = result.text.lower()
- if hyperlinks.has_key(key) and hyperlinks[key]!=target:
- # The following try-except is a quick hack to ensure that the
- # program will not stop because of problems in the warning
- # mechanism. One such specific problem is a UnicodeEncodeError
- # when result.text contains difficult characters.
- try:
- warnings.warn("Ignoring second appearance of anchor '" + result.text +
- "' with different target")
- except:
- pass
- return result
- hyperlinks[key] = target
- result.text = '`'+result.text+'`_'
- return result
-
-def handleHeading(node):
- contents = mergeChildren(node)
- if contents.empty(): return contents
- result = HeadingDitem(node.nodeName)
- result.children.append(contents)
- return result
-
-def handleEmphasis(node):
- result = mergeChildren(node)
- result.type = node.nodeName
- if result.text:
- result.text = '*' + result.text + '*'
- return result
-
-def handleStrong(node):
- result = mergeChildren(node)
- result.type = node.nodeName
- if result.text:
- result.text = '**' + result.text + '**'
- return result
-
-def handleGenericBlock(node):
- result = BlockDitem(node.nodeName)
- result.children = processChildren(node)
- return result
-
-def handleBlockQuote(node):
- result = BlockQuoteDitem(node.nodeName)
- result.children = processChildren(node)
- return result
-
-def handleList(node):
- result = ListDitem(node.nodeName)
- result.children = processChildren(node)
- return result
-
-def handleListItem(node):
- result = ListItemDitem(node.nodeName)
- result.children = processChildren(node)
- return result
-
-def handleTable(node):
- result = TableDitem(node.nodeName)
- # Ignore table contents that are not tr
- result.children = [x
- for x in processChildren(node) if x.type=='tr']
- return result
-
-def handleTr(node):
- result = TrDitem(node.nodeName)
- # Ignore tr contents that are not th or td
- result.children = [x
- for x in processChildren(node) if x.type in ('th', 'td')]
- return result
-
-def handlePre(node):
- return PreDitem(mergeChildren(node).text)
-
-dom1 = xml.dom.minidom.parse(sys.argv[1])
-ditem = handleNode(dom1.getElementsByTagName("body")[0])
-ditem.propagate_indents()
-(utf8_encode, utf8_decode, utf8_reader, utf8_writer) = codecs.lookup('utf-8')
-outf = utf8_writer(sys.stdout)
-outf.write(ditem.format(79) + '\n')
-for h in hyperlinks.keys():
- outf.write('\n.. _`' + h + '`:\n ' + hyperlinks[h] + '\n')