[Zope-Checkins] SVN: Zope/trunk/lib/python/docutils/ Updated
docutils to 0.3.4 (merge from tiran-restfixing-branch)
Christian 'Tiran' Heimes
heimes at faho.rwth-aachen.de
Thu May 13 11:25:54 EDT 2004
Log message for revision 24625:
Updated docutils to 0.3.4 (merge from tiran-restfixing-branch)
-=-
Modified: Zope/trunk/lib/python/docutils/__init__.py
===================================================================
--- Zope/trunk/lib/python/docutils/__init__.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/__init__.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:04 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:37 $
# Copyright: This module has been placed in the public domain.
"""
@@ -51,12 +51,14 @@
__docformat__ = 'reStructuredText'
-__version__ = '0.3.1'
-"""``major.minor.micro`` version number. The micro number is bumped any time
-there's a change in the API incompatible with one of the front ends or
-significant new functionality. The minor number is bumped whenever there is a
+__version__ = '0.3.4'
+"""``major.minor.micro`` version number. The micro number is bumped
+any time there's a change in the API incompatible with one of the
+front ends or significant new functionality, and at any alpha or beta
+release. The minor number is bumped whenever there is a stable
project release. The major number will be bumped when the project is
-feature-complete, and perhaps if there is a major change in the design."""
+feature-complete, and perhaps if there is a major change in the
+design."""
class ApplicationError(StandardError): pass
@@ -122,18 +124,35 @@
default_transforms = ()
"""Transforms required by this class. Override in subclasses."""
+
+ unknown_reference_resolvers = ()
+ """List of functions to try to resolve unknown references. Called when
+ FinalCheckVisitor is unable to find a correct target. The list should
+ contain functions which will try to resolve unknown references, with the
+ following signature::
+ def reference_resolver(node):
+ '''Returns boolean: true if resolved, false if not.'''
+ Each function must have a "priority" attribute which will affect the order
+ the unknown_reference_resolvers are run::
+
+ reference_resolver.priority = 100
+
+ Override in subclasses."""
+
+
class Component(SettingsSpec, TransformSpec):
"""Base class for Docutils components."""
component_type = None
- """Override in subclasses."""
+ """Name of the component type ('reader', 'parser', 'writer'). Override in
+ subclasses."""
supported = ()
"""Names for this component. Override in subclasses."""
-
+
def supports(self, format):
"""
Is `format` supported by this component?
Modified: Zope/trunk/lib/python/docutils/core.py
===================================================================
--- Zope/trunk/lib/python/docutils/core.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/core.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Authors: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:04 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:38 $
# Copyright: This module has been placed in the public domain.
"""
@@ -180,6 +180,7 @@
self.settings)
self.apply_transforms(document)
output = self.writer.write(document, self.destination)
+ self.writer.assemble_parts()
except utils.SystemMessage, error:
if self.settings.traceback:
raise
@@ -376,3 +377,63 @@
pub.set_source(source, source_path)
pub.set_destination(destination_path=destination_path)
return pub.publish(enable_exit=enable_exit)
+
+def publish_parts(source, source_path=None, destination_path=None,
+ reader=None, reader_name='standalone',
+ parser=None, parser_name='restructuredtext',
+ writer=None, writer_name='pseudoxml',
+ settings=None, settings_spec=None,
+ settings_overrides=None, config_section=None,
+ enable_exit=None):
+ """
+ Set up & run a `Publisher`, and return a dictionary of document parts.
+ Dictionary keys are the names of parts, and values are Unicode strings;
+ encoding is up to the client. For programmatic use with string I/O.
+
+ For encoded string input, be sure to set the "input_encoding" setting to
+ the desired encoding. Set it to "unicode" for unencoded Unicode string
+ input. Here's how::
+
+ publish_string(..., settings_overrides={'input_encoding': 'unicode'})
+
+ Parameters:
+
+ - `source`: An input string; required. This can be an encoded 8-bit
+ string (set the "input_encoding" setting to the correct encoding) or a
+ Unicode string (set the "input_encoding" setting to "unicode").
+ - `source_path`: Path to the file or object that produced `source`;
+ optional. Only used for diagnostic output.
+ - `destination_path`: Path to the file or object which will receive the
+ output; optional. Used for determining relative paths (stylesheets,
+ source links, etc.).
+ - `reader`: A `docutils.readers.Reader` object.
+ - `reader_name`: Name or alias of the Reader class to be instantiated if
+ no `reader` supplied.
+ - `parser`: A `docutils.parsers.Parser` object.
+ - `parser_name`: Name or alias of the Parser class to be instantiated if
+ no `parser` supplied.
+ - `writer`: A `docutils.writers.Writer` object.
+ - `writer_name`: Name or alias of the Writer class to be instantiated if
+ no `writer` supplied.
+ - `settings`: Runtime settings object.
+ - `settings_spec`: Extra settings specification; a `docutils.SettingsSpec`
+ subclass. Used only if no `settings` specified.
+ - `settings_overrides`: A dictionary containing program-specific overrides
+ of component settings.
+ - `config_section`: Name of configuration file section for application.
+ Used only if no `settings` or `settings_spec` specified.
+ - `enable_exit`: Boolean; enable exit status at end of processing?
+ """
+ pub = Publisher(reader, parser, writer, settings=settings,
+ source_class=io.StringInput,
+ destination_class=io.NullOutput)
+ pub.set_components(reader_name, parser_name, writer_name)
+ if settings is None:
+ settings = pub.get_settings(settings_spec=settings_spec,
+ config_section=config_section)
+ if settings_overrides:
+ settings._update(settings_overrides, 'loose')
+ pub.set_source(source, source_path)
+ pub.set_destination(destination_path=destination_path)
+ pub.publish(enable_exit=enable_exit)
+ return pub.writer.parts
Added: Zope/trunk/lib/python/docutils/examples.py
===================================================================
--- Zope/trunk/lib/python/docutils/examples.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/examples.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -0,0 +1,74 @@
+# Authors: David Goodger
+# Contact: goodger at python.org
+# Revision: $Revision: 1.1.2.1 $
+# Date: $Date: 2004/05/12 19:57:38 $
+# Copyright: This module has been placed in the public domain.
+
+"""
+This module contains practical examples of Docutils client code.
+
+Importing this module is not recommended; its contents are subject to change
+in future Docutils releases. Instead, it is recommended that you copy and
+paste the parts you need into your own code, modifying as necessary.
+"""
+
+from docutils import core
+
+
+def html_parts(input_string, source_path=None, destination_path=None,
+ input_encoding='unicode', doctitle=1, initial_header_level=1):
+ """
+ Given an input string, returns a dictionary of HTML document parts.
+
+ Dictionary keys are the names of parts, and values are Unicode strings;
+ encoding is up to the client.
+
+ Parameters:
+
+ - `input_string`: A multi-line text string; required.
+ - `source_path`: Path to the source file or object. Optional, but useful
+ for diagnostic output (system messages).
+ - `destination_path`: Path to the file or object which will receive the
+ output; optional. Used for determining relative paths (stylesheets,
+ source links, etc.).
+ - `input_encoding`: The encoding of `input_string`. If it is an encoded
+ 8-bit string, provide the correct encoding. If it is a Unicode string,
+ use "unicode", the default.
+ - `doctitle`: Disable the promotion of a lone top-level section title to
+ document title (and subsequent section title to document subtitle
+ promotion); enabled by default.
+ - `initial_header_level`: The initial level for header elements (e.g. 1
+ for "<h1>").
+ """
+ overrides = {'input_encoding': input_encoding,
+ 'doctitle_xform': doctitle,
+ 'initial_header_level': initial_header_level}
+ parts = core.publish_parts(
+ source=input_string, source_path=source_path,
+ destination_path=destination_path,
+ writer_name='html', settings_overrides=overrides)
+ return parts
+
+def html_fragment(input_string, source_path=None, destination_path=None,
+ input_encoding='unicode', output_encoding='unicode',
+ doctitle=1, initial_header_level=1):
+ """
+ Given an input string, returns an HTML fragment as a string.
+
+ The return value is the contents of the <body> tag, less the title,
+ subtitle, and docinfo.
+
+ Parameters (see `html_parts()` for the remainder):
+
+ - `output_encoding`: The desired encoding of the output. If a Unicode
+ string is desired, use the default value of "unicode" .
+ """
+ parts = html_parts(
+ input_string=input_string, source_path=source_path,
+ destination_path=destination_path,
+ input_encoding=input_encoding, doctitle=doctitle,
+ initial_header_level=initial_header_level)
+ fragment = parts['fragment']
+ if output_encoding != 'unicode':
+ fragment = fragment.encode(output_encoding)
+ return fragment
Modified: Zope/trunk/lib/python/docutils/frontend.py
===================================================================
--- Zope/trunk/lib/python/docutils/frontend.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/frontend.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.7 $
-# Date: $Date: 2003/11/30 15:06:04 $
+# Revision: $Revision: 1.2.10.4.8.1 $
+# Date: $Date: 2004/05/12 19:57:38 $
# Copyright: This module has been placed in the public domain.
"""
@@ -126,8 +126,7 @@
def validate_threshold(setting, value, option_parser,
config_parser=None, config_section=None):
try:
- int(value)
- return value
+ return int(value)
except ValueError:
try:
return option_parser.thresholds[value.lower()]
@@ -294,6 +293,10 @@
('Disable backlinks from footnotes and citations.',
['--no-footnote-backlinks'],
{'dest': 'footnote_backlinks', 'action': 'store_false'}),
+ ('Disable Docutils section numbering',
+ ['--no-section-numbering'],
+ {'action': 'store_false', 'dest': 'sectnum_xform',
+ 'default': 1, 'validator': validate_boolean}),
('Set verbosity threshold; report system messages at or higher than '
'<level> (by name or number: "info" or "1", warning/2, error/3, '
'severe/4; also, "none" or "5"). Default is 2 (warning).',
@@ -346,7 +349,7 @@
{'metavar': '<name[:handler]>', 'default': 'utf-8',
'validator': validate_encoding_and_error_handler}),
(SUPPRESS_HELP, # usually handled by --output-encoding
- ['--output_encoding_error_handler'],
+ ['--output-encoding-error-handler'],
{'default': 'strict', 'validator': validate_encoding_error_handler}),
('Specify the text encoding for error output. Default is ASCII. '
'Optionally also specify the encoding error handler for unencodable '
@@ -357,7 +360,7 @@
{'metavar': '<name[:handler]>', 'default': 'ascii',
'validator': validate_encoding_and_error_handler}),
(SUPPRESS_HELP, # usually handled by --error-encoding
- ['--error_encoding_error_handler'],
+ ['--error-encoding-error-handler'],
{'default': default_error_encoding_error_handler,
'validator': validate_encoding_error_handler}),
('Specify the language of input text (ISO 639 2-letter identifier).'
Modified: Zope/trunk/lib/python/docutils/io.py
===================================================================
--- Zope/trunk/lib/python/docutils/io.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/io.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:04 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:38 $
# Copyright: This module has been placed in the public domain.
"""
@@ -12,7 +12,10 @@
__docformat__ = 'reStructuredText'
import sys
-import locale
+try:
+ import locale
+except:
+ pass
from types import UnicodeType
from docutils import TransformSpec
@@ -156,7 +159,7 @@
print >>sys.stderr, '%s: %s' % (error.__class__.__name__,
error)
print >>sys.stderr, (
- 'Unable to open source file for reading (%s). Exiting.'
+ 'Unable to open source file for reading (%r). Exiting.'
% source_path)
sys.exit(1)
else:
@@ -224,7 +227,7 @@
print >>sys.stderr, '%s: %s' % (error.__class__.__name__,
error)
print >>sys.stderr, ('Unable to open destination file for writing '
- '(%s). Exiting.' % source_path)
+ '(%r). Exiting.' % self.destination_path)
sys.exit(1)
self.opened = 1
Modified: Zope/trunk/lib/python/docutils/languages/__init__.py
===================================================================
--- Zope/trunk/lib/python/docutils/languages/__init__.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/languages/__init__.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:05 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:42 $
# Copyright: This module has been placed in the public domain.
# Internationalization details are documented in
Modified: Zope/trunk/lib/python/docutils/languages/af.py
===================================================================
--- Zope/trunk/lib/python/docutils/languages/af.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/languages/af.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: Jannie Hofmeyr
# Contact: jhsh at sun.ac.za
-# Revision: $Revision: 1.3 $
-# Date: $Date: 2003/11/30 15:06:05 $
+# Revision: $Revision: 1.1.2.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:42 $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
Added: Zope/trunk/lib/python/docutils/languages/cs.py
===================================================================
--- Zope/trunk/lib/python/docutils/languages/cs.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/languages/cs.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -0,0 +1,62 @@
+# Author: Marek Blaha
+# Contact: mb at dat.cz
+# Revision: $Revision: 1.1.2.1 $
+# Date: $Date: 2004/05/12 19:57:42 $
+# Copyright: This module has been placed in the public domain.
+
+# New language mappings are welcome. Before doing a new translation, please
+# read <http://docutils.sf.net/spec/howto/i18n.html>. Two files must be
+# translated for each language: one in docutils/languages, the other in
+# docutils/parsers/rst/languages.
+
+"""
+Czech-language mappings for language-dependent features of Docutils.
+"""
+
+__docformat__ = 'reStructuredText'
+
+labels = {
+ # fixed: language-dependent
+ 'author': u'Autor',
+ 'authors': u'Auto\u0159i',
+ 'organization': u'Organizace',
+ 'address': u'Adresa',
+ 'contact': u'Kontakt',
+ 'version': u'Verze',
+ 'revision': u'Revize',
+ 'status': u'Stav',
+ 'date': u'Datum',
+ 'copyright': u'Copyright',
+ 'dedication': u'V\u011Bnov\u00E1n\u00ED',
+ 'abstract': u'Abstrakt',
+ 'attention': u'Pozor!',
+ 'caution': u'Opatrn\u011B!',
+ 'danger': u'!NEBEZPE\u010C\u00CD!',
+ 'error': u'Chyba',
+ 'hint': u'Rada',
+ 'important': u'D\u016Fle\u017Eit\u00E9',
+ 'note': u'Pozn\u00E1mka',
+ 'tip': u'Tip',
+ 'warning': u'Varov\u00E1n\u00ED',
+ 'contents': u'Obsah'}
+"""Mapping of node class name to label text."""
+
+bibliographic_fields = {
+ # language-dependent: fixed
+ u'autor': 'author',
+ u'auto\u0159i': 'authors',
+ u'organizace': 'organization',
+ u'adresa': 'address',
+ u'kontakt': 'contact',
+ u'verze': 'version',
+ u'revize': 'revision',
+ u'stav': 'status',
+ u'datum': 'date',
+ u'copyright': 'copyright',
+ u'v\u011Bnov\u00E1n\u00ED': 'dedication',
+ u'abstrakt': 'abstract'}
+"""Czech (lowcased) to canonical name mapping for bibliographic fields."""
+
+author_separators = [';', ',']
+"""List of separator strings for the 'Authors' bibliographic field. Tried in
+order."""
Modified: Zope/trunk/lib/python/docutils/languages/de.py
===================================================================
--- Zope/trunk/lib/python/docutils/languages/de.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/languages/de.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Authors: David Goodger; Gunnar Schwant
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:05 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:42 $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
Modified: Zope/trunk/lib/python/docutils/languages/en.py
===================================================================
--- Zope/trunk/lib/python/docutils/languages/en.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/languages/en.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:05 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:42 $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
Modified: Zope/trunk/lib/python/docutils/languages/eo.py
===================================================================
--- Zope/trunk/lib/python/docutils/languages/eo.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/languages/eo.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: Marcelo Huerta San Martin
# Contact: richieadler at users.sourceforge.net
-# Revision: $Revision: 1.1 $
-# Date: $Date: 2003/11/30 15:06:05 $
+# Revision: $Revision: 1.1.2.1.8.1 $
+# Date: $Date: 2004/05/12 19:57:42 $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
Modified: Zope/trunk/lib/python/docutils/languages/es.py
===================================================================
--- Zope/trunk/lib/python/docutils/languages/es.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/languages/es.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,8 +1,8 @@
# -*- coding: iso-8859-1 -*-
# Author: Marcelo Huerta San Martín
# Contact: mghsm at uol.com.ar
-# Revision: $Revision: 1.3 $
-# Date: $Date: 2003/11/30 15:06:05 $
+# Revision: $Revision: 1.1.2.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:42 $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
Modified: Zope/trunk/lib/python/docutils/languages/fr.py
===================================================================
--- Zope/trunk/lib/python/docutils/languages/fr.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/languages/fr.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: Stefane Fermigier
# Contact: sf at fermigier.com
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:05 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:42 $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
Modified: Zope/trunk/lib/python/docutils/languages/it.py
===================================================================
--- Zope/trunk/lib/python/docutils/languages/it.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/languages/it.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: Nicola Larosa
# Contact: docutils at tekNico.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:05 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:42 $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
Added: Zope/trunk/lib/python/docutils/languages/pt_br.py
===================================================================
--- Zope/trunk/lib/python/docutils/languages/pt_br.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/languages/pt_br.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -0,0 +1,63 @@
+# -*- coding: iso-8859-1 -*-
+# Author: David Goodger
+# Contact: goodger at users.sourceforge.net
+# Revision: $Revision: 1.1.2.1 $
+# Date: $Date: 2004/05/12 19:57:42 $
+# Copyright: This module has been placed in the public domain.
+
+# New language mappings are welcome. Before doing a new translation, please
+# read <http://docutils.sf.net/spec/howto/i18n.html>. Two files must be
+# translated for each language: one in docutils/languages, the other in
+# docutils/parsers/rst/languages.
+
+"""
+Brazilian Portuguese-language mappings for language-dependent features of Docutils.
+"""
+
+__docformat__ = 'reStructuredText'
+
+labels = {
+ # fixed: language-dependent
+ 'author': u'Autor',
+ 'authors': u'Autores',
+ 'organization': unicode('Organização', 'latin1'),
+ 'address': unicode('Endereço', 'latin1'),
+ 'contact': u'Contato',
+ 'version': unicode('Versão', 'latin1'),
+ 'revision': unicode('Revisão', 'latin1'),
+ 'status': u'Estado',
+ 'date': u'Data',
+ 'copyright': u'Copyright',
+ 'dedication': unicode('Dedicatória', 'latin1'),
+ 'abstract': u'Resumo',
+ 'attention': unicode('Attenção!', 'latin1'),
+ 'caution': u'Cuidado!',
+ 'danger': u'PERIGO!',
+ 'error': u'Erro',
+ 'hint': unicode('Sugestão', 'latin1'),
+ 'important': u'Importante',
+ 'note': u'Nota',
+ 'tip': u'Dica',
+ 'warning': u'Aviso',
+ 'contents': unicode('Sumário', 'latin1')}
+"""Mapping of node class name to label text."""
+
+bibliographic_fields = {
+ # language-dependent: fixed
+ u'autor': 'author',
+ u'autores': 'authors',
+ unicode('organização', 'latin1'): 'organization',
+ unicode('endereço', 'latin1'): 'address',
+ u'contato': 'contact',
+ unicode('versão', 'latin1'): 'version',
+ unicode('revisão', 'latin1'): 'revision',
+ u'estado': 'status',
+ u'data': 'date',
+ u'copyright': 'copyright',
+ unicode('dedicatória', 'latin1'): 'dedication',
+ u'resumo': 'abstract'}
+"""English (lowcased) to canonical name mapping for bibliographic fields."""
+
+author_separators = [';', ',']
+"""List of separator strings for the 'Authors' bibliographic field. Tried in
+order."""
Modified: Zope/trunk/lib/python/docutils/languages/ru.py
===================================================================
--- Zope/trunk/lib/python/docutils/languages/ru.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/languages/ru.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: Roman Suzi
# Contact: rnd at onego.ru
-# Revision: $Revision: 1.3 $
-# Date: $Date: 2003/11/30 15:06:05 $
+# Revision: $Revision: 1.1.2.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:42 $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
Modified: Zope/trunk/lib/python/docutils/languages/sk.py
===================================================================
--- Zope/trunk/lib/python/docutils/languages/sk.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/languages/sk.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# :Author: Miroslav Vasko
# :Contact: zemiak at zoznam.sk
-# :Revision: $Revision: 1.5 $
-# :Date: $Date: 2003/11/30 15:06:05 $
+# :Revision: $Revision: 1.2.10.3.8.1 $
+# :Date: $Date: 2004/05/12 19:57:42 $
# :Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
Modified: Zope/trunk/lib/python/docutils/languages/sv.py
===================================================================
--- Zope/trunk/lib/python/docutils/languages/sv.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/languages/sv.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: Adam Chodorowski
# Contact: chodorowski at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:05 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:42 $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
Modified: Zope/trunk/lib/python/docutils/nodes.py
===================================================================
--- Zope/trunk/lib/python/docutils/nodes.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/nodes.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:04 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:38 $
# Copyright: This module has been placed in the public domain.
"""
@@ -517,6 +517,9 @@
its immediate parent is a `TextElement` instance (including subclasses).
This is handy for nodes like `image` that can appear both inline and as
standalone body elements.
+
+ If passing children to `__init__()`, make sure to set `text` to
+ ``''`` or some other suitable value.
"""
child_text_separator = ''
@@ -599,6 +602,9 @@
referenced = 0
+ indirect_reference_name = None
+ """Holds the whitespace_normalized_name (contains mixed case) of a target"""
+
class Labeled:
"""Contains a `label` as its first element."""
@@ -820,6 +826,7 @@
def has_name(self, name):
return self.nameids.has_key(name)
+ # "note" here is an imperative verb: "take note of".
def note_implicit_target(self, target, msgnode=None):
id = self.set_id(target, msgnode)
self.set_name_id_map(target, id, msgnode, explicit=None)
@@ -939,6 +946,7 @@
# ========================
class docinfo(Bibliographic, Element): pass
+class info(Bibliographic, Element): pass
class author(Bibliographic, TextElement): pass
class authors(Bibliographic, Element): pass
class organization(Bibliographic, TextElement): pass
@@ -1182,7 +1190,7 @@
class emphasis(Inline, TextElement): pass
class strong(Inline, TextElement): pass
class literal(Inline, TextElement): pass
-class reference(Inline, Referential, TextElement): pass
+class reference(General, Inline, Referential, TextElement): pass
class footnote_reference(Inline, Referential, TextElement): pass
class citation_reference(Inline, Referential, TextElement): pass
class substitution_reference(Inline, TextElement): pass
@@ -1222,7 +1230,7 @@
footnote footnote_reference
generated
header hint
- image important inline
+ image important info inline
label legend line_block list_item literal literal_block
note
option option_argument option_group option_list option_list_item
@@ -1273,8 +1281,8 @@
Raise an exception unless overridden.
"""
- raise NotImplementedError('visiting unknown node type: %s'
- % node.__class__.__name__)
+ raise NotImplementedError('%s visiting unknown node type: %s'
+ % (self.__class__, node.__class__.__name__))
def unknown_departure(self, node):
"""
@@ -1282,8 +1290,8 @@
Raise exception unless overridden.
"""
- raise NotImplementedError('departing unknown node type: %s'
- % node.__class__.__name__)
+ raise NotImplementedError('%s departing unknown node type: %s'
+ % (self.__class__, node.__class__.__name__))
class SparseNodeVisitor(NodeVisitor):
@@ -1295,16 +1303,6 @@
subclasses), subclass `NodeVisitor` instead.
"""
-def _nop(self, node):
- pass
-
-# Save typing with dynamic assignments:
-for _name in node_class_names:
- setattr(SparseNodeVisitor, "visit_" + _name, _nop)
- setattr(SparseNodeVisitor, "depart_" + _name, _nop)
-del _name, _nop
-
-
class GenericNodeVisitor(NodeVisitor):
"""
@@ -1337,13 +1335,19 @@
def _call_default_departure(self, node):
self.default_departure(node)
-# Save typing with dynamic assignments:
-for _name in node_class_names:
- setattr(GenericNodeVisitor, "visit_" + _name, _call_default_visit)
- setattr(GenericNodeVisitor, "depart_" + _name, _call_default_departure)
-del _name, _call_default_visit, _call_default_departure
+def _nop(self, node):
+ pass
+def _add_node_class_names(names):
+ """Save typing with dynamic assignments:"""
+ for _name in names:
+ setattr(GenericNodeVisitor, "visit_" + _name, _call_default_visit)
+ setattr(GenericNodeVisitor, "depart_" + _name, _call_default_departure)
+ setattr(SparseNodeVisitor, 'visit_' + _name, _nop)
+ setattr(SparseNodeVisitor, 'depart' + _name, _nop)
+_add_node_class_names(node_class_names)
+
class TreeCopyVisitor(GenericNodeVisitor):
"""
Modified: Zope/trunk/lib/python/docutils/parsers/__init__.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/__init__.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/__init__.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:06 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:45 $
# Copyright: This module has been placed in the public domain.
"""
Modified: Zope/trunk/lib/python/docutils/parsers/rst/__init__.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/__init__.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/__init__.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:07:46 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:46 $
# Copyright: This module has been placed in the public domain.
"""
Modified: Zope/trunk/lib/python/docutils/parsers/rst/directives/__init__.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/directives/__init__.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/directives/__init__.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.6 $
-# Date: $Date: 2003/11/30 15:06:06 $
+# Revision: $Revision: 1.2.10.4.8.1 $
+# Date: $Date: 2004/05/12 19:57:48 $
# Copyright: This module has been placed in the public domain.
"""
@@ -102,6 +102,7 @@
'epigraph': ('body', 'epigraph'),
'highlights': ('body', 'highlights'),
'pull-quote': ('body', 'pull_quote'),
+ 'table': ('body', 'table'),
#'questions': ('body', 'question_list'),
'image': ('images', 'image'),
'figure': ('images', 'figure'),
@@ -117,6 +118,7 @@
'replace': ('misc', 'replace'),
'unicode': ('misc', 'unicode_directive'),
'class': ('misc', 'class_directive'),
+ 'role': ('misc', 'role'),
'restructuredtext-test-directive': ('misc', 'directive_test_function'),}
"""Mapping of directive name to (module name, function name). The directive
name is canonical & must be lowercase. Language-dependent names are defined
@@ -165,23 +167,37 @@
try:
modulename, functionname = _directive_registry[canonicalname]
except KeyError:
+ messages.append(document.reporter.error(
+ 'Directive "%s" not registered (canonical name "%s").'
+ % (directive_name, canonicalname), line=document.current_line))
return None, messages
if _modules.has_key(modulename):
module = _modules[modulename]
else:
try:
module = __import__(modulename, globals(), locals())
- except ImportError:
+ except ImportError, detail:
+ messages.append(document.reporter.error(
+ 'Error importing directive module "%s" (directive "%s"):\n%s'
+ % (modulename, directive_name, detail),
+ line=document.current_line))
return None, messages
try:
function = getattr(module, functionname)
_directives[normname] = function
except AttributeError:
+ messages.append(document.reporter.error(
+ 'No function "%s" in module "%s" (directive "%s").'
+ % (functionname, modulename, directive_name),
+ line=document.current_line))
return None, messages
return function, messages
def register_directive(name, directive):
- """Register a nonstandard application-defined directive function."""
+ """
+ Register a nonstandard application-defined directive function.
+ Language lookups are not needed for such functions.
+ """
_directives[name] = directive
def flag(argument):
@@ -257,7 +273,10 @@
"""
if argument is None:
raise ValueError('argument required but none supplied')
- return nodes.make_id(argument)
+ class_name = nodes.make_id(argument)
+ if not class_name:
+ raise ValueError('cannot make "%s" into a class name' % argument)
+ return class_name
def format_values(values):
return '%s, or "%s"' % (', '.join(['"%s"' % s for s in values[:-1]]),
Modified: Zope/trunk/lib/python/docutils/parsers/rst/directives/admonitions.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/directives/admonitions.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/directives/admonitions.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:06 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:48 $
# Copyright: This module has been placed in the public domain.
"""
Modified: Zope/trunk/lib/python/docutils/parsers/rst/directives/body.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/directives/body.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/directives/body.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:06 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:48 $
# Copyright: This module has been placed in the public domain.
"""
@@ -34,6 +34,7 @@
title_text = arguments[0]
textnodes, messages = state.inline_text(title_text, lineno)
titles = [nodes.title(title_text, '', *textnodes)]
+ # sidebar uses this code
if options.has_key('subtitle'):
textnodes, more_messages = state.inline_text(options['subtitle'],
lineno)
@@ -120,3 +121,38 @@
return [block_quote] + messages
pull_quote.content = 1
+
+def table(name, arguments, options, content, lineno,
+ content_offset, block_text, state, state_machine):
+ if not content:
+ warning = state_machine.reporter.warning(
+ 'Content block expected for the "%s" directive; none found.'
+ % name, nodes.literal_block(block_text, block_text),
+ line=lineno)
+ return [warning]
+ if arguments:
+ title_text = arguments[0]
+ text_nodes, messages = state.inline_text(title_text, lineno)
+ title = nodes.title(title_text, '', *text_nodes)
+ else:
+ title = None
+ node = nodes.Element() # anonymous container for parsing
+ text = '\n'.join(content)
+ state.nested_parse(content, content_offset, node)
+ if len(node) != 1 or not isinstance(node[0], nodes.table):
+ error = state_machine.reporter.error(
+ 'Error parsing content block for the "%s" directive: '
+ 'exactly one table expected.'
+ % name, nodes.literal_block(block_text, block_text),
+ line=lineno)
+ return [error]
+ table_node = node[0]
+ if options.has_key('class'):
+ table_node.set_class(options['class'])
+ if title:
+ table_node.insert(0, title)
+ return [table_node]
+
+table.arguments = (0, 1, 1)
+table.options = {'class': directives.class_option}
+table.content = 1
Modified: Zope/trunk/lib/python/docutils/parsers/rst/directives/html.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/directives/html.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/directives/html.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:06 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:48 $
# Copyright: This module has been placed in the public domain.
"""
Modified: Zope/trunk/lib/python/docutils/parsers/rst/directives/images.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/directives/images.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/directives/images.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:06 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:48 $
# Copyright: This module has been placed in the public domain.
"""
@@ -13,7 +13,8 @@
import sys
from docutils import nodes, utils
-from docutils.parsers.rst import directives
+from docutils.parsers.rst import directives, states
+from docutils.nodes import whitespace_normalize_name
try:
import Image # PIL
@@ -34,8 +35,23 @@
nodes.literal_block(block_text, block_text), line=lineno)
return [error]
options['uri'] = reference
- image_node = nodes.image(block_text, **options)
- return [image_node]
+ if options.has_key('target'):
+ block = states.escape2null(options['target']).splitlines()
+ block = [line for line in block]
+ target_type, data = state.parse_target(block, block_text, lineno)
+ if target_type == 'refuri':
+ node_list = nodes.reference(refuri=data)
+ elif target_type == 'refname':
+ node_list = nodes.reference(
+ refname=data, name=whitespace_normalize_name(options['target']))
+ state.document.note_refname(node_list)
+ else: # malformed target
+ node_list = [data] # data is a system message
+ del options['target']
+ else:
+ node_list = []
+ node_list.append(nodes.image(block_text, **options))
+ return node_list
image.arguments = (1, 0, 1)
image.options = {'alt': directives.unchanged,
@@ -43,6 +59,7 @@
'width': directives.nonnegative_int,
'scale': directives.nonnegative_int,
'align': align,
+ 'target': directives.unchanged_required,
'class': directives.class_option}
def figure(name, arguments, options, content, lineno,
Modified: Zope/trunk/lib/python/docutils/parsers/rst/directives/misc.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/directives/misc.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/directives/misc.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Authors: David Goodger, Dethe Elza
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:06 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:48 $
# Copyright: This module has been placed in the public domain.
"""Miscellaneous directives."""
@@ -11,12 +11,16 @@
import sys
import os.path
import re
-from urllib2 import urlopen, URLError
from docutils import io, nodes, statemachine, utils
-from docutils.parsers.rst import directives, states
+from docutils.parsers.rst import directives, roles, states
from docutils.transforms import misc
+try:
+ import urllib2
+except ImportError:
+ urllib2 = None
+
def include(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
"""Include a reST file as part of the content of this reST file."""
@@ -97,9 +101,16 @@
raw_file.close()
attributes['source'] = path
elif options.has_key('url'):
+ if not urllib2:
+ severe = state_machine.reporter.severe(
+ 'Problems with the "%s" directive and its "url" option: '
+ 'unable to access the required functionality (from the '
+ '"urllib2" module).' % name,
+ nodes.literal_block(block_text, block_text), line=lineno)
+ return [severe]
try:
- raw_file = urlopen(options['url'])
- except (URLError, IOError, OSError), error:
+ raw_file = urllib2.urlopen(options['url'])
+ except (urllib2.URLError, IOError, OSError), error:
severe = state_machine.reporter.severe(
'Problems with "%s" directive URL "%s":\n%s.'
% (name, options['url'], error),
@@ -209,7 +220,7 @@
return [pending]
else:
error = state_machine.reporter.error(
- 'Invalid class attribute value for "%s" directive: %s'
+ 'Invalid class attribute value for "%s" directive: "%s".'
% (name, arguments[0]),
nodes.literal_block(block_text, block_text), line=lineno)
return [error]
@@ -217,8 +228,67 @@
class_directive.arguments = (1, 0, 0)
class_directive.content = 1
+role_arg_pat = re.compile(r'(%s)\s*(\(\s*(%s)\s*\)\s*)?$'
+ % ((states.Inliner.simplename,) * 2))
+def role(name, arguments, options, content, lineno,
+ content_offset, block_text, state, state_machine):
+ """Dynamically create and register a custom interpreted text role."""
+ if content_offset > lineno or not content:
+ error = state_machine.reporter.error(
+ '"%s" directive requires arguments on the first line.'
+ % name, nodes.literal_block(block_text, block_text), line=lineno)
+ return [error]
+ args = content[0]
+ match = role_arg_pat.match(args)
+ if not match:
+ error = state_machine.reporter.error(
+ '"%s" directive arguments not valid role names: "%s".'
+ % (name, args), nodes.literal_block(block_text, block_text),
+ line=lineno)
+ return [error]
+ new_role_name = match.group(1)
+ base_role_name = match.group(3)
+ messages = []
+ if base_role_name:
+ base_role, messages = roles.role(
+ base_role_name, state_machine.language, lineno, state.reporter)
+ if base_role is None:
+ error = state.reporter.error(
+ 'Unknown interpreted text role "%s".' % base_role_name,
+ nodes.literal_block(block_text, block_text), line=lineno)
+ return messages + [error]
+ else:
+ base_role = roles.generic_custom_role
+ assert not hasattr(base_role, 'arguments'), (
+ 'Supplemental directive arguments for "%s" directive not supported'
+ '(specified by "%r" role).' % (name, base_role))
+ try:
+ (arguments, options, content, content_offset) = (
+ state.parse_directive_block(content[1:], content_offset, base_role,
+ option_presets={}))
+ except states.MarkupError, detail:
+ error = state_machine.reporter.error(
+ 'Error in "%s" directive:\n%s.' % (name, detail),
+ nodes.literal_block(block_text, block_text), line=lineno)
+ return messages + [error]
+ if not options.has_key('class'):
+ try:
+ options['class'] = directives.class_option(new_role_name)
+ except ValueError, detail:
+ error = state_machine.reporter.error(
+ 'Invalid argument for "%s" directive:\n%s.'
+ % (name, detail),
+ nodes.literal_block(block_text, block_text), line=lineno)
+ return messages + [error]
+ role = roles.CustomRole(new_role_name, base_role, options, content)
+ roles.register_local_role(new_role_name, role)
+ return messages
+
+role.content = 1
+
def directive_test_function(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
+ """This directive is useful only for testing purposes."""
if content:
text = '\n'.join(content)
info = state_machine.reporter.info(
Modified: Zope/trunk/lib/python/docutils/parsers/rst/directives/parts.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/directives/parts.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/directives/parts.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger, Dmitry Jemerov
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:06 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:48 $
# Copyright: This module has been placed in the public domain.
"""
@@ -10,7 +10,7 @@
__docformat__ = 'reStructuredText'
-from docutils import nodes
+from docutils import nodes, languages
from docutils.transforms import parts
from docutils.parsers.rst import directives
@@ -27,17 +27,42 @@
def contents(name, arguments, options, content, lineno,
content_offset, block_text, state, state_machine):
"""Table of contents."""
+ document = state_machine.document
+ language = languages.get_language(document.settings.language_code)
+
if arguments:
title_text = arguments[0]
text_nodes, messages = state.inline_text(title_text, lineno)
title = nodes.title(title_text, '', *text_nodes)
else:
messages = []
- title = None
- pending = nodes.pending(parts.Contents, {'title': title}, block_text)
+ if options.has_key('local'):
+ title = None
+ else:
+ title = nodes.title('', language.labels['contents'])
+
+ topic = nodes.topic(CLASS='contents')
+
+ cls = options.get('class')
+ if cls:
+ topic.set_class(cls)
+
+ if title:
+ name = title.astext()
+ topic += title
+ else:
+ name = language.labels['contents']
+
+ name = nodes.fully_normalize_name(name)
+ if not document.has_name(name):
+ topic['name'] = name
+ document.note_implicit_target(topic)
+
+ pending = nodes.pending(parts.Contents, rawsource=block_text)
pending.details.update(options)
- state_machine.document.note_pending(pending)
- return [pending] + messages
+ document.note_pending(pending)
+ topic += pending
+ return [topic] + messages
contents.arguments = (0, 1, 1)
contents.options = {'depth': directives.nonnegative_int,
Modified: Zope/trunk/lib/python/docutils/parsers/rst/directives/references.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/directives/references.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/directives/references.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger, Dmitry Jemerov
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:06 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:48 $
# Copyright: This module has been placed in the public domain.
"""
Modified: Zope/trunk/lib/python/docutils/parsers/rst/languages/__init__.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/languages/__init__.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/languages/__init__.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:07 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:50 $
# Copyright: This module has been placed in the public domain.
# Internationalization details are documented in
Modified: Zope/trunk/lib/python/docutils/parsers/rst/languages/af.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/languages/af.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/languages/af.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: Jannie Hofmeyr
# Contact: jhsh at sun.ac.za
-# Revision: $Revision: 1.3 $
-# Date: $Date: 2003/11/30 15:06:07 $
+# Revision: $Revision: 1.1.2.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:50 $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
@@ -36,6 +36,7 @@
'epigraaf': 'epigraph',
'hoogtepunte': 'highlights',
'pull-quote (translation required)': 'pull-quote',
+ 'table (translation required)': 'table',
#'vrae': 'questions',
#'qa': 'questions',
#'faq': 'questions',
@@ -48,6 +49,7 @@
'vervang': 'replace',
'unicode': 'unicode', # should this be translated? unikode
'klas': 'class',
+ 'role (translation required)': 'role',
'inhoud': 'contents',
'sectnum': 'sectnum',
'section-numbering': 'sectnum',
Added: Zope/trunk/lib/python/docutils/parsers/rst/languages/cs.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/languages/cs.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/languages/cs.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -0,0 +1,96 @@
+# Author: Marek Blaha
+# Contact: mb at dat.cz
+# Revision: $Revision: 1.1.2.1 $
+# Date: $Date: 2004/05/12 19:57:50 $
+# Copyright: This module has been placed in the public domain.
+
+# New language mappings are welcome. Before doing a new translation, please
+# read <http://docutils.sf.net/spec/howto/i18n.html>. Two files must be
+# translated for each language: one in docutils/languages, the other in
+# docutils/parsers/rst/languages.
+
+"""
+Czech-language mappings for language-dependent features of
+reStructuredText.
+"""
+
+__docformat__ = 'reStructuredText'
+
+
+directives = {
+ # language-dependent: fixed
+ u'pozor': 'attention',
+ u'caution': 'caution', # jak rozlisit caution a warning?
+ u'nebezpe\u010D\u00ED': 'danger',
+ u'chyba': 'error',
+ u'rada': 'hint',
+ u'd\u016Fle\u017Eit\u00E9': 'important',
+ u'pozn\u00E1mka': 'note',
+ u'tip': 'tip',
+ u'varov\u00E1n\u00ED': 'warning',
+ u'admonition': 'admonition',
+ u'sidebar': 'sidebar',
+ u't\u00E9ma': 'topic',
+ u'line-block': 'line-block',
+ u'parsed-literal': 'parsed-literal',
+ u'odd\u00EDl': 'rubric',
+ u'moto': 'epigraph',
+ u'highlights': 'highlights',
+ u'pull-quote': 'pull-quote',
+ u'table (translation required)': 'table',
+ #'questions': 'questions',
+ #'qa': 'questions',
+ #'faq': 'questions',
+ u'meta': 'meta',
+ #'imagemap': 'imagemap',
+ u'image': 'image', # obrazek
+ u'figure': 'figure', # a tady?
+ u'include': 'include',
+ u'raw': 'raw',
+ u'replace': 'replace',
+ u'unicode': 'unicode',
+ u't\u0159\u00EDda': 'class',
+ u'role (translation required)': 'role',
+ u'obsah': 'contents',
+ u'sectnum': 'sectnum',
+ u'section-numbering': 'sectnum',
+ #'footnotes': 'footnotes',
+ #'citations': 'citations',
+ u'target-notes': 'target-notes',
+ u'restructuredtext-test-directive': 'restructuredtext-test-directive'}
+"""Czech name to registered (in directives/__init__.py) directive name
+mapping."""
+
+roles = {
+ # language-dependent: fixed
+ u'abbreviation': 'abbreviation',
+ u'ab': 'abbreviation',
+ u'acronym': 'acronym',
+ u'ac': 'acronym',
+ u'index': 'index',
+ u'i': 'index',
+ u'subscript': 'subscript',
+ u'sub': 'subscript',
+ u'superscript': 'superscript',
+ u'sup': 'superscript',
+ u'title-reference': 'title-reference',
+ u'title': 'title-reference',
+ u't': 'title-reference',
+ u'pep-reference': 'pep-reference',
+ u'pep': 'pep-reference',
+ u'rfc-reference': 'rfc-reference',
+ u'rfc': 'rfc-reference',
+ u'emphasis': 'emphasis',
+ u'strong': 'strong',
+ u'literal': 'literal',
+ u'named-reference': 'named-reference',
+ u'anonymous-reference': 'anonymous-reference',
+ u'footnote-reference': 'footnote-reference',
+ u'citation-reference': 'citation-reference',
+ u'substitution-reference': 'substitution-reference',
+ u'target': 'target',
+ u'uri-reference': 'uri-reference',
+ u'uri': 'uri-reference',
+ u'url': 'uri-reference',}
+"""Mapping of Czech role names to canonical role names for interpreted text.
+"""
Modified: Zope/trunk/lib/python/docutils/parsers/rst/languages/de.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/languages/de.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/languages/de.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,8 +1,8 @@
# -*- coding: iso-8859-1 -*-
# Author: Engelbert Gruber
# Contact: grubert at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:07 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:50 $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
@@ -37,6 +37,7 @@
'epigraph (translation required)': 'epigraph',
'highlights (translation required)': 'highlights',
'pull-quote (translation required)': 'pull-quote', # kasten too ?
+ 'table (translation required)': 'table',
#'questions': 'questions',
#'qa': 'questions',
#'faq': 'questions',
@@ -49,7 +50,8 @@
# einfügung would be the noun.
'ersetzung': 'replace', # ersetzen, ersetze
'unicode': 'unicode',
- 'klasse': 'class', # offer class too ?
+ 'klasse': 'class', # offer "class" too ?
+ 'role (translation required)': 'role',
'inhalt': 'contents',
'sectnum': 'sectnum',
'section-numbering': 'sectnum',
Modified: Zope/trunk/lib/python/docutils/parsers/rst/languages/en.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/languages/en.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/languages/en.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:07 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:50 $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
@@ -37,6 +37,7 @@
'epigraph': 'epigraph',
'highlights': 'highlights',
'pull-quote': 'pull-quote',
+ 'table': 'table',
#'questions': 'questions',
#'qa': 'questions',
#'faq': 'questions',
@@ -49,6 +50,7 @@
'replace': 'replace',
'unicode': 'unicode',
'class': 'class',
+ 'role': 'role',
'contents': 'contents',
'sectnum': 'sectnum',
'section-numbering': 'sectnum',
Modified: Zope/trunk/lib/python/docutils/parsers/rst/languages/eo.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/languages/eo.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/languages/eo.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: Marcelo Huerta San Martin
# Contact: richieadler at users.sourceforge.net
-# Revision: $Revision: 1.1 $
-# Date: $Date: 2003/11/30 15:06:07 $
+# Revision: $Revision: 1.1.2.1.8.1 $
+# Date: $Date: 2004/05/12 19:57:50 $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
@@ -40,6 +40,7 @@
u'elstara\u0135oj': 'highlights',
u'ekstera-citajxo': 'pull-quote',
u'ekstera-cita\u0135o': 'pull-quote',
+ u'tabelo': 'table',
#'questions': 'questions',
#'qa': 'questions',
#'faq': 'questions',
@@ -53,6 +54,7 @@
u'anstata\u016di': 'replace',
u'unicode': 'unicode',
u'klaso': 'class',
+ u'rolo': 'role',
u'enhavo': 'contents',
u'seknum': 'sectnum',
u'sekcia-numerado': 'sectnum',
Modified: Zope/trunk/lib/python/docutils/parsers/rst/languages/es.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/languages/es.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/languages/es.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,8 +1,8 @@
# -*- coding: iso-8859-1 -*-
# Author: Marcelo Huerta San Martín
# Contact: mghsm at uol.com.ar
-# Revision: $Revision: 1.3 $
-# Date: $Date: 2003/11/30 15:06:07 $
+# Revision: $Revision: 1.1.2.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:51 $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
@@ -42,6 +42,7 @@
u'epigrafe': 'epigraph',
u'destacado': 'highlights',
u'cita-destacada': 'pull-quote',
+ u'tabla': 'table',
#'questions': 'questions',
#'qa': 'questions',
#'faq': 'questions',
@@ -54,6 +55,7 @@
u'reemplazar': 'replace',
u'unicode': 'unicode',
u'clase': 'class',
+ u'rol': 'role',
u'contenido': 'contents',
u'numseccion': 'sectnum',
u'numsecci\u00f3n': 'sectnum',
@@ -74,8 +76,10 @@
u'ac': 'acronym',
u'indice': 'index',
u'i': 'index',
- u'subscript (translation required)': 'subscript',
- u'superscript (translation required)': 'superscript',
+ u'subindice': 'subscript',
+ u'sub\u00edndice': 'subscript',
+ u'superindice': 'superscript',
+ u'super\u00edndice': 'superscript',
u'referencia-titulo': 'title-reference',
u'titulo': 'title-reference',
u't': 'title-reference',
Modified: Zope/trunk/lib/python/docutils/parsers/rst/languages/fr.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/languages/fr.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/languages/fr.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Authors: David Goodger; William Dode
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:07 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:51 $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
@@ -38,6 +38,7 @@
u'\u00E9pigraphe': 'epigraph',
u'chapeau': 'highlights',
u'accroche': 'pull-quote',
+ u'tableau': 'table',
#u'questions': 'questions',
#u'qr': 'questions',
#u'faq': 'questions',
@@ -51,6 +52,7 @@
u'remplace': 'replace',
u'unicode': 'unicode',
u'classe': 'class',
+ u'role (translation required)': 'role',
u'sommaire': 'contents',
u'table-des-mati\u00E8res': 'contents',
u'sectnum': 'sectnum',
Modified: Zope/trunk/lib/python/docutils/parsers/rst/languages/it.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/languages/it.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/languages/it.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,14 +1,9 @@
-# Author: Nicola Larosa
-# Contact: docutils at tekNico.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:07 $
+# Author: Nicola Larosa, Lele Gaifax
+# Contact: docutils at tekNico.net, lele at seldati.it
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:51 $
# Copyright: This module has been placed in the public domain.
-# New language mappings are welcome. Before doing a new translation, please
-# read <http://docutils.sf.net/spec/howto/i18n.html>. Two files must be
-# translated for each language: one in docutils/languages, the other in
-# docutils/parsers/rst/languages.
-
"""
Italian-language mappings for language-dependent features of
reStructuredText.
@@ -27,15 +22,16 @@
'nota': 'note',
'consiglio': 'tip',
'avvertenza': 'warning',
- 'admonition (translation required)': 'admonition',
- 'sidebar (translation required)': 'sidebar',
+ 'ammonizione': 'admonition',
+ 'riquadro': 'sidebar',
'argomento': 'topic',
- 'blocco di linee': 'line-block',
- 'parsed-literal': 'parsed-literal',
- 'rubric (translation required)': 'rubric',
- 'epigraph (translation required)': 'epigraph',
- 'highlights (translation required)': 'highlights',
+ 'blocco-di-righe': 'line-block',
+ 'blocco-interpretato': 'parsed-literal',
+ 'rubrica': 'rubric',
+ 'epigrafe': 'epigraph',
+ 'evidenzia': 'highlights',
'pull-quote (translation required)': 'pull-quote',
+ 'tabella': 'table',
#'questions': 'questions',
#'qa': 'questions',
#'faq': 'questions',
@@ -47,11 +43,12 @@
'grezzo': 'raw',
'sostituisci': 'replace',
'unicode': 'unicode',
- 'class (translation required)': 'class',
+ 'classe': 'class',
+ 'ruolo': 'role',
'indice': 'contents',
'seznum': 'sectnum',
- 'section-numbering': 'sectnum',
- 'target-notes': 'target-notes',
+ 'sezioni-autonumerate': 'sectnum',
+ 'annota-riferimenti-esterni': 'target-notes',
#'footnotes': 'footnotes',
#'citations': 'citations',
'restructuredtext-test-directive': 'restructuredtext-test-directive'}
@@ -59,23 +56,23 @@
mapping."""
roles = {
- 'abbreviation (translation required)': 'abbreviation',
- 'acronym (translation required)': 'acronym',
- 'index (translation required)': 'index',
- 'subscript (translation required)': 'subscript',
- 'superscript (translation required)': 'superscript',
- 'title-reference (translation required)': 'title-reference',
- 'pep-reference (translation required)': 'pep-reference',
- 'rfc-reference (translation required)': 'rfc-reference',
- 'emphasis (translation required)': 'emphasis',
- 'strong (translation required)': 'strong',
- 'literal (translation required)': 'literal',
- 'named-reference (translation required)': 'named-reference',
- 'anonymous-reference (translation required)': 'anonymous-reference',
- 'footnote-reference (translation required)': 'footnote-reference',
- 'citation-reference (translation required)': 'citation-reference',
- 'substitution-reference (translation required)': 'substitution-reference',
- 'target (translation required)': 'target',
- 'uri-reference (translation required)': 'uri-reference',}
+ 'abbreviazione': 'abbreviation',
+ 'acronimo': 'acronym',
+ 'indice': 'index',
+ 'deponente': 'subscript',
+ 'esponente': 'superscript',
+ 'riferimento-titolo': 'title-reference',
+ 'riferimento-pep': 'pep-reference',
+ 'riferimento-rfc': 'rfc-reference',
+ 'enfasi': 'emphasis',
+ 'forte': 'strong',
+ 'letterale': 'literal',
+ 'riferimento-con-nome': 'named-reference',
+ 'riferimento-anonimo': 'anonymous-reference',
+ 'riferimento-nota': 'footnote-reference',
+ 'riferimento-citazione': 'citation-reference',
+ 'riferimento-sostituzione': 'substitution-reference',
+ 'destinazione': 'target',
+ 'riferimento-uri': 'uri-reference',}
"""Mapping of Italian role names to canonical role names for interpreted text.
"""
Added: Zope/trunk/lib/python/docutils/parsers/rst/languages/pt_br.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/languages/pt_br.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/languages/pt_br.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -0,0 +1,97 @@
+# -*- coding: iso-8859-1 -*-
+# Author: David Goodger
+# Contact: goodger at users.sourceforge.net
+# Revision: $Revision: 1.1.2.1 $
+# Date: $Date: 2004/05/12 19:57:51 $
+# Copyright: This module has been placed in the public domain.
+
+# New language mappings are welcome. Before doing a new translation, please
+# read <http://docutils.sf.net/spec/howto/i18n.html>. Two files must be
+# translated for each language: one in docutils/languages, the other in
+# docutils/parsers/rst/languages.
+
+"""
+Brazilian Portuguese-language mappings for language-dependent features of
+reStructuredText.
+"""
+
+__docformat__ = 'reStructuredText'
+
+
+directives = {
+ # language-dependent: fixed
+ u'atenção': 'attention',
+ 'cuidado': 'caution',
+ 'perigo': 'danger',
+ 'erro': 'error',
+ u'sugestão': 'hint',
+ 'importante': 'important',
+ 'nota': 'note',
+ 'dica': 'tip',
+ 'aviso': 'warning',
+ u'exortação': 'admonition',
+ 'barra-lateral': 'sidebar',
+ u'tópico': 'topic',
+ 'bloco-de-linhas': 'line-block',
+ 'literal-interpretado': 'parsed-literal',
+ 'rubrica': 'rubric',
+ u'epígrafo': 'epigraph',
+ 'destaques': 'highlights',
+ u'citação-destacada': 'pull-quote',
+ u'table (translation required)': 'table',
+ #'perguntas': 'questions',
+ #'qa': 'questions',
+ #'faq': 'questions',
+ 'meta': 'meta',
+ #'imagemap': 'imagemap',
+ 'imagem': 'image',
+ 'figura': 'figure',
+ u'inclusão': 'include',
+ 'cru': 'raw',
+ u'substituição': 'replace',
+ 'unicode': 'unicode',
+ 'classe': 'class',
+ 'role (translation required)': 'role',
+ u'índice': 'contents',
+ 'numsec': 'sectnum',
+ u'numeração-de-seções': 'sectnum',
+ #u'notas-de-rorapé': 'footnotes',
+ #u'citações': 'citations',
+ u'links-no-rodapé': 'target-notes',
+ 'restructuredtext-test-directive': 'restructuredtext-test-directive'}
+"""English name to registered (in directives/__init__.py) directive name
+mapping."""
+
+roles = {
+ # language-dependent: fixed
+ u'abbreviação': 'abbreviation',
+ 'ab': 'abbreviation',
+ u'acrônimo': 'acronym',
+ 'ac': 'acronym',
+ u'índice-remissivo': 'index',
+ 'i': 'index',
+ 'subscrito': 'subscript',
+ 'sub': 'subscript',
+ 'sobrescrito': 'superscript',
+ 'sob': 'superscript',
+ u'referência-a-título': 'title-reference',
+ u'título': 'title-reference',
+ 't': 'title-reference',
+ u'referência-a-pep': 'pep-reference',
+ 'pep': 'pep-reference',
+ u'referência-a-rfc': 'rfc-reference',
+ 'rfc': 'rfc-reference',
+ u'ênfase': 'emphasis',
+ 'forte': 'strong',
+ 'literal': 'literal',
+ u'referência-por-nome': 'named-reference',
+ u'referência-anônima': 'anonymous-reference',
+ u'referência-a-nota-de-rodapé': 'footnote-reference',
+ u'referência-a-citação': 'citation-reference',
+ u'referência-a-substituição': 'substitution-reference',
+ 'alvo': 'target',
+ u'referência-a-uri': 'uri-reference',
+ 'uri': 'uri-reference',
+ 'url': 'uri-reference',}
+"""Mapping of English role names to canonical role names for interpreted text.
+"""
Modified: Zope/trunk/lib/python/docutils/parsers/rst/languages/ru.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/languages/ru.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/languages/ru.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: Roman Suzi
# Contact: rnd at onego.ru
-# Revision: $Revision: 1.3 $
-# Date: $Date: 2003/11/30 15:06:07 $
+# Revision: $Revision: 1.1.2.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:51 $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
@@ -23,6 +23,7 @@
u'parsed-literal',
u'\u0432\u044b\u0434\u0435\u043b\u0435\u043d\u043d\u0430\u044f-\u0446\u0438\u0442\u0430\u0442\u0430':
u'pull-quote',
+ u'table (translation required)': 'table',
u'\u0441\u044b\u0440\u043e\u0439': u'raw',
u'\u0437\u0430\u043c\u0435\u043d\u0430': u'replace',
u'\u0442\u0435\u0441\u0442\u043e\u0432\u0430\u044f-\u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u0430-restructuredtext':
@@ -40,6 +41,7 @@
u'\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435':
u'image',
u'\u043a\u043b\u0430\u0441\u0441': u'class',
+ u'role (translation required)': 'role',
u'\u043d\u043e\u043c\u0435\u0440-\u0440\u0430\u0437\u0434\u0435\u043b\u0430':
u'sectnum',
u'\u043d\u0443\u043c\u0435\u0440\u0430\u0446\u0438\u044f-\u0440\u0430\u0437'
Modified: Zope/trunk/lib/python/docutils/parsers/rst/languages/sk.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/languages/sk.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/languages/sk.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: Miroslav Vasko
# Contact: zemiak at zoznam.sk
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:07 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:51 $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
@@ -36,6 +36,7 @@
u'epigraph (translation required)': 'epigraph',
u'highlights (translation required)': 'highlights',
u'pull-quote (translation required)': 'pull-quote',
+ u'table (translation required)': 'table',
#u'questions': 'questions',
#u'qa': 'questions',
#u'faq': 'questions',
@@ -48,6 +49,7 @@
u'nahradi\x9d': 'replace',
u'unicode': 'unicode',
u'class (translation required)': 'class',
+ u'role (translation required)': 'role',
u'obsah': 'contents',
u'\xe8as\x9d': 'sectnum',
u'\xe8as\x9d-\xe8\xedslovanie': 'sectnum',
Modified: Zope/trunk/lib/python/docutils/parsers/rst/languages/sv.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/languages/sv.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/languages/sv.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: Adam Chodorowski
# Contact: chodorowski at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:07 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:51 $
# Copyright: This module has been placed in the public domain.
# New language mappings are welcome. Before doing a new translation, please
@@ -35,6 +35,7 @@
u'epigraph (translation required)': 'epigraph',
u'highlights (translation required)': 'highlights',
u'pull-quote (translation required)': 'pull-quote',
+ u'table (translation required)': 'table',
# u'fr\u00e5gor': 'questions',
# NOTE: A bit long, but recommended by http://www.nada.kth.se/dataterm/:
# u'fr\u00e5gor-och-svar': 'questions',
@@ -48,6 +49,7 @@
u'ers\u00e4tt': 'replace',
u'unicode': 'unicode',
u'class (translation required)': 'class',
+ u'role (translation required)': 'role',
u'inneh\u00e5ll': 'contents',
u'sektionsnumrering': 'sectnum',
u'target-notes (translation required)': 'target-notes',
Added: Zope/trunk/lib/python/docutils/parsers/rst/roles.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/roles.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/roles.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -0,0 +1,312 @@
+# Author: Edward Loper
+# Contact: edloper at gradient.cis.upenn.edu
+# Revision: $Revision: 1.1.2.1 $
+# Date: $Date: 2004/05/12 19:57:46 $
+# Copyright: This module has been placed in the public domain.
+
+"""
+This module defines standard interpreted text role functions, a registry for
+interpreted text roles, and an API for adding to and retrieving from the
+registry.
+
+The interface for interpreted role functions is as follows::
+
+ def role_fn(name, rawtext, text, lineno, inliner,
+ options={}, content=[]):
+ code...
+
+ # Set function attributes for customization:
+ role_fn.options = ...
+ role_fn.content = ...
+
+Parameters:
+
+- ``name`` is the local name of the interpreted text role, the role name
+ actually used in the document.
+
+- ``rawtext`` is a string containing the entire interpreted text construct.
+ Return it as a ``problematic`` node linked to a system message if there is a
+ problem.
+
+- ``text`` is the interpreted text content.
+
+- ``lineno`` is the line number where the interpreted text beings.
+
+- ``inliner`` is the Inliner object that called the role function.
+ It defines the following useful attributes: ``reporter``,
+ ``problematic``, ``memo``, ``parent``, ``document``.
+
+- ``options``: A dictionary of directive options for customization, to be
+ interpreted by the role function. Used for additional attributes for the
+ generated elements and other functionality.
+
+- ``content``: A list of strings, the directive content for customization
+ ("role" directive). To be interpreted by the role function.
+
+Function attributes for customization, interpreted by the "role" directive:
+
+- ``options``: A dictionary, mapping known option names to conversion
+ functions such as `int` or `float`. ``None`` or an empty dict implies no
+ options to parse. Several directive option conversion functions are defined
+ in the `directives` module.
+
+ All role functions implicitly support the "class" option, unless disabled
+ with an explicit ``{'class': None}``.
+
+- ``content``: A boolean; true if content is allowed. Client code must handle
+ the case where content is required but not supplied (an empty content list
+ will be supplied).
+
+Note that unlike directives, the "arguments" function attribute is not
+supported for role customization. Directive arguments are handled by the
+"role" directive itself.
+
+Interpreted role functions return a tuple of two values:
+
+- A list of nodes which will be inserted into the document tree at the
+ point where the interpreted role was encountered (can be an empty
+ list).
+
+- A list of system messages, which will be inserted into the document tree
+ immediately after the end of the current inline block (can also be empty).
+"""
+
+__docformat__ = 'reStructuredText'
+
+from docutils import nodes
+from docutils.parsers.rst import directives
+from docutils.parsers.rst.languages import en as _fallback_language_module
+
+DEFAULT_INTERPRETED_ROLE = 'title-reference'
+"""
+The canonical name of the default interpreted role. This role is used
+when no role is specified for a piece of interpreted text.
+"""
+
+_role_registry = {}
+"""Mapping of canonical role names to role functions. Language-dependent role
+names are defined in the ``language`` subpackage."""
+
+_roles = {}
+"""Mapping of local or language-dependent interpreted text role names to role
+functions."""
+
+def role(role_name, language_module, lineno, reporter):
+ """
+ Locate and return a role function from its language-dependent name, along
+ with a list of system messages. If the role is not found in the current
+ language, check English. Return a 2-tuple: role function (``None`` if the
+ named role cannot be found) and a list of system messages.
+ """
+ normname = role_name.lower()
+ messages = []
+ msg_text = []
+
+ if _roles.has_key(normname):
+ return _roles[normname], messages
+
+ if role_name:
+ canonicalname = None
+ try:
+ canonicalname = language_module.roles[normname]
+ except AttributeError, error:
+ msg_text.append('Problem retrieving role entry from language '
+ 'module %r: %s.' % (language_module, error))
+ except KeyError:
+ msg_text.append('No role entry for "%s" in module "%s".'
+ % (role_name, language_module.__name__))
+ else:
+ canonicalname = DEFAULT_INTERPRETED_ROLE
+
+ # If we didn't find it, try English as a fallback.
+ if not canonicalname:
+ try:
+ canonicalname = _fallback_language_module.roles[normname]
+ msg_text.append('Using English fallback for role "%s".'
+ % role_name)
+ except KeyError:
+ msg_text.append('Trying "%s" as canonical role name.'
+ % role_name)
+ # The canonical name should be an English name, but just in case:
+ canonicalname = normname
+
+ # Collect any messages that we generated.
+ if msg_text:
+ message = reporter.info('\n'.join(msg_text), line=lineno)
+ messages.append(message)
+
+ # Look the role up in the registry, and return it.
+ if _role_registry.has_key(canonicalname):
+ role_fn = _role_registry[canonicalname]
+ register_local_role(normname, role_fn)
+ return role_fn, messages
+ else:
+ return None, messages # Error message will be generated by caller.
+
+def register_canonical_role(name, role_fn):
+ """
+ Register an interpreted text role by its canonical name.
+
+ :Parameters:
+ - `name`: The canonical name of the interpreted role.
+ - `role_fn`: The role function. See the module docstring.
+ """
+ set_implicit_options(role_fn)
+ _role_registry[name] = role_fn
+
+def register_local_role(name, role_fn):
+ """
+ Register an interpreted text role by its local or language-dependent name.
+
+ :Parameters:
+ - `name`: The local or language-dependent name of the interpreted role.
+ - `role_fn`: The role function. See the module docstring.
+ """
+ set_implicit_options(role_fn)
+ _roles[name] = role_fn
+
+def set_implicit_options(role_fn):
+ """
+ Add customization options to role functions, unless explicitly set or
+ disabled.
+ """
+ if not hasattr(role_fn, 'options') or role_fn.options is None:
+ role_fn.options = {'class': directives.class_option}
+ elif not role_fn.options.has_key('class'):
+ role_fn.options['class'] = directives.class_option
+
+def register_generic_role(canonical_name, node_class):
+ """For roles which simply wrap a given `node_class` around the text."""
+ role = GenericRole(canonical_name, node_class)
+ register_canonical_role(canonical_name, role)
+
+
+class GenericRole:
+
+ """
+ Generic interpreted text role, where the interpreted text is simply
+ wrapped with the provided node class.
+ """
+
+ def __init__(self, role_name, node_class):
+ self.name = role_name
+ self.node_class = node_class
+
+ def __call__(self, role, rawtext, text, lineno, inliner,
+ options={}, content=[]):
+ return [self.node_class(rawtext, text, **options)], []
+
+
+class CustomRole:
+
+ """
+ Wrapper for custom interpreted text roles.
+ """
+
+ def __init__(self, role_name, base_role, options={}, content=[]):
+ self.name = role_name
+ self.base_role = base_role
+ self.options = None
+ if hasattr(base_role, 'options'):
+ self.options = base_role.options
+ self.content = None
+ if hasattr(base_role, 'content'):
+ self.content = base_role.content
+ self.supplied_options = options
+ self.supplied_content = content
+
+ def __call__(self, role, rawtext, text, lineno, inliner,
+ options={}, content=[]):
+ opts = self.supplied_options.copy()
+ opts.update(options)
+ cont = list(self.supplied_content)
+ if cont and content:
+ cont += '\n'
+ cont.extend(content)
+ return self.base_role(role, rawtext, text, lineno, inliner,
+ options=opts, content=cont)
+
+
+def generic_custom_role(role, rawtext, text, lineno, inliner,
+ options={}, content=[]):
+ """"""
+ # Once nested inline markup is implemented, this and other methods should
+ # recursively call inliner.nested_parse().
+ return [nodes.inline(rawtext, text, **options)], []
+
+generic_custom_role.options = {'class': directives.class_option}
+
+
+######################################################################
+# Define and register the standard roles:
+######################################################################
+
+register_generic_role('abbreviation', nodes.abbreviation)
+register_generic_role('acronym', nodes.acronym)
+register_generic_role('emphasis', nodes.emphasis)
+register_generic_role('literal', nodes.literal)
+register_generic_role('strong', nodes.strong)
+register_generic_role('subscript', nodes.subscript)
+register_generic_role('superscript', nodes.superscript)
+register_generic_role('title-reference', nodes.title_reference)
+
+def pep_reference_role(role, rawtext, text, lineno, inliner,
+ options={}, content=[]):
+ try:
+ pepnum = int(text)
+ if pepnum < 0 or pepnum > 9999:
+ raise ValueError
+ except ValueError:
+ msg = inliner.reporter.error(
+ 'PEP number must be a number from 0 to 9999; "%s" is invalid.'
+ % text, line=lineno)
+ prb = inliner.problematic(rawtext, rawtext, msg)
+ return [prb], [msg]
+ # Base URL mainly used by inliner.pep_reference; so this is correct:
+ ref = inliner.pep_url % pepnum
+ return [nodes.reference(rawtext, 'PEP ' + text, refuri=ref, **options)], []
+
+register_canonical_role('pep-reference', pep_reference_role)
+
+def rfc_reference_role(role, rawtext, text, lineno, inliner,
+ options={}, content=[]):
+ try:
+ rfcnum = int(text)
+ if rfcnum <= 0:
+ raise ValueError
+ except ValueError:
+ msg = inliner.reporter.error(
+ 'RFC number must be a number greater than or equal to 1; '
+ '"%s" is invalid.' % text, line=lineno)
+ prb = inliner.problematic(rawtext, rawtext, msg)
+ return [prb], [msg]
+ # Base URL mainly used by inliner.rfc_reference, so this is correct:
+ ref = inliner.rfc_url % rfcnum
+ node = nodes.reference(rawtext, 'RFC ' + text, refuri=ref, **options)
+ return [node], []
+
+register_canonical_role('rfc-reference', rfc_reference_role)
+
+
+######################################################################
+# Register roles that are currently unimplemented.
+######################################################################
+
+def unimplemented_role(role, rawtext, text, lineno, inliner, attributes={}):
+ msg = inliner.reporter.error(
+ 'Interpreted text role "%s" not implemented.' % role, line=lineno)
+ prb = inliner.problematic(rawtext, rawtext, msg)
+ return [prb], [msg]
+
+register_canonical_role('index', unimplemented_role)
+register_canonical_role('named-reference', unimplemented_role)
+register_canonical_role('anonymous-reference', unimplemented_role)
+register_canonical_role('uri-reference', unimplemented_role)
+register_canonical_role('footnote-reference', unimplemented_role)
+register_canonical_role('citation-reference', unimplemented_role)
+register_canonical_role('substitution-reference', unimplemented_role)
+register_canonical_role('target', unimplemented_role)
+
+# This should remain unimplemented, for testing purposes:
+register_canonical_role('restructuredtext-unimplemented-role',
+ unimplemented_role)
Modified: Zope/trunk/lib/python/docutils/parsers/rst/states.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/states.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/states.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:07:46 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:46 $
# Copyright: This module has been placed in the public domain.
"""
@@ -107,13 +107,14 @@
import sys
import re
-from docutils import roman
+import roman
from types import TupleType
from docutils import nodes, statemachine, utils, urischemes
from docutils import ApplicationError, DataError
from docutils.statemachine import StateMachineWS, StateWS
from docutils.nodes import fully_normalize_name as normalize_name
-from docutils.parsers.rst import directives, languages, tableparser
+from docutils.nodes import whitespace_normalize_name
+from docutils.parsers.rst import directives, languages, tableparser, roles
from docutils.parsers.rst.languages import en as _fallback_language_module
@@ -274,7 +275,7 @@
state_machine.unlink()
new_offset = state_machine.abs_line_offset()
# No `block.parent` implies disconnected -- lines aren't in sync:
- if block.parent:
+ if block.parent and (len(block) - block_length) != 0:
# Adjustment for block if modified in nested parse:
self.state_machine.next_line(len(block) - block_length)
return new_offset
@@ -475,46 +476,6 @@
Parse inline markup; call the `parse()` method.
"""
- _interpreted_roles = {
- # Values of ``None`` mean "not implemented yet":
- 'title-reference': 'generic_interpreted_role',
- 'abbreviation': 'generic_interpreted_role',
- 'acronym': 'generic_interpreted_role',
- 'index': None,
- 'subscript': 'generic_interpreted_role',
- 'superscript': 'generic_interpreted_role',
- 'emphasis': 'generic_interpreted_role',
- 'strong': 'generic_interpreted_role',
- 'literal': 'generic_interpreted_role',
- 'named-reference': None,
- 'anonymous-reference': None,
- 'uri-reference': None,
- 'pep-reference': 'pep_reference_role',
- 'rfc-reference': 'rfc_reference_role',
- 'footnote-reference': None,
- 'citation-reference': None,
- 'substitution-reference': None,
- 'target': None,
- 'restructuredtext-unimplemented-role': None}
- """Mapping of canonical interpreted text role name to method name.
- Initializes a name to bound-method mapping in `__init__`."""
-
- default_interpreted_role = 'title-reference'
- """The role to use when no explicit role is given.
- Override in subclasses."""
-
- generic_roles = {'abbreviation': nodes.abbreviation,
- 'acronym': nodes.acronym,
- 'emphasis': nodes.emphasis,
- 'literal': nodes.literal,
- 'strong': nodes.strong,
- 'subscript': nodes.subscript,
- 'superscript': nodes.superscript,
- 'title-reference': nodes.title_reference,}
- """Mapping of canonical interpreted text role name to node class.
- Used by the `generic_interpreted_role` method for simple, straightforward
- roles (simple wrapping; no extra processing)."""
-
def __init__(self, roles=None):
"""
`roles` is a mapping of canonical role name to role function or bound
@@ -525,17 +486,6 @@
"""List of (pattern, bound method) tuples, used by
`self.implicit_inline`."""
- self.interpreted_roles = {}
- """Mapping of canonical role name to role function or bound method.
- Items removed from this mapping will be disabled."""
-
- for canonical, method in self._interpreted_roles.items():
- if method:
- self.interpreted_roles[canonical] = getattr(self, method)
- else:
- self.interpreted_roles[canonical] = None
- self.interpreted_roles.update(roles or {})
-
def init_customizations(self, settings):
"""Setting-based customizations; run when parsing begins."""
if settings.pep_references:
@@ -546,6 +496,8 @@
self.rfc_reference))
def parse(self, text, lineno, memo, parent):
+ # Needs to be refactored for nested inline markup.
+ # Add nested_parse() method?
"""
Return 2 lists: nodes (text and inline elements), and system_messages.
@@ -601,11 +553,12 @@
non_whitespace_after = r'(?![ \n])'
# Alphanumerics with isolated internal [-._] chars (i.e. not 2 together):
simplename = r'(?:(?!_)\w)+(?:[-._](?:(?!_)\w)+)*'
- # Valid URI characters (see RFC 2396 & RFC 2732):
- uric = r"""[-_.!~*'()[\];/:@&=+$,%a-zA-Z0-9]"""
+ # Valid URI characters (see RFC 2396 & RFC 2732);
+ # final \x00 allows backslash escapes in URIs:
+ uric = r"""[-_.!~*'()[\];/:@&=+$,%a-zA-Z0-9\x00]"""
# Last URI character; same as uric but no punctuation:
urilast = r"""[_~/a-zA-Z0-9]"""
- emailc = r"""[-_!~*'{|}/#?^`&=+$%a-zA-Z0-9]"""
+ emailc = r"""[-_!~*'{|}/#?^`&=+$%a-zA-Z0-9\x00]"""
email_pattern = r"""
%(emailc)s+(?:\.%(emailc)s+)* # name
@ # at
@@ -659,10 +612,10 @@
embedded_uri=re.compile(
r"""
(
- [ \n]+ # spaces or beginning of line
+ (?:[ \n]+|^) # spaces or beginning of line/string
< # open bracket
%(non_whitespace_after)s
- ([^<>\0]+) # anything but angle brackets & nulls
+ ([^<>\x00]+) # anything but angle brackets & nulls
%(non_whitespace_before)s
> # close bracket w/o whitespace before
)
@@ -823,26 +776,11 @@
return self.phrase_ref(string[:matchstart], string[textend:],
rawsource, escaped, text)
else:
- try:
- return self.interpreted(
- string[:rolestart], string[textend:],
- rawsource, text, role, lineno)
- except UnknownInterpretedRoleError, detail:
- msg = self.reporter.error(
- 'Unknown interpreted text role "%s".' % role,
- line=lineno)
- text = unescape(string[rolestart:textend], 1)
- prb = self.problematic(text, text, msg)
- return (string[:rolestart], [prb], string[textend:],
- detail.args[0] + [msg])
- except InterpretedRoleNotImplementedError, detail:
- msg = self.reporter.error(
- 'Interpreted text role "%s" not implemented.' % role,
- line=lineno)
- text = unescape(string[rolestart:textend], 1)
- prb = self.problematic(text, text, msg)
- return (string[:rolestart], [prb], string[textend:],
- detail.args[0] + [msg])
+ rawsource = unescape(string[rolestart:textend], 1)
+ nodelist, messages = self.interpreted(rawsource, text, role,
+ lineno)
+ return (string[:rolestart], nodelist,
+ string[textend:], messages)
msg = self.reporter.warning(
'Inline interpreted text or phrase reference start-string '
'without end-string.', line=lineno)
@@ -861,10 +799,13 @@
target = nodes.target(match.group(1), refuri=uri)
else:
raise ApplicationError('problem with URI: %r' % uri_text)
+ if not text:
+ text = uri
else:
target = None
refname = normalize_name(text)
- reference = nodes.reference(rawsource, text)
+ reference = nodes.reference(rawsource, text,
+ name=whitespace_normalize_name(text))
node_list = [reference]
if rawsource[-2:] == '__':
if target:
@@ -891,51 +832,19 @@
else:
return uri
- def interpreted(self, before, after, rawsource, text, role, lineno):
- role_function, canonical, messages = self.get_role_function(role,
- lineno)
- if role_function:
- nodelist, messages2 = role_function(canonical, rawsource, text,
- lineno)
- messages.extend(messages2)
- return before, nodelist, after, messages
+ def interpreted(self, rawsource, text, role, lineno):
+ role_fn, messages = roles.role(role, self.language, lineno,
+ self.reporter)
+ if role_fn:
+ nodes, messages2 = role_fn(role, rawsource, text, lineno, self)
+ return nodes, messages + messages2
else:
- raise InterpretedRoleNotImplementedError(messages)
+ msg = self.reporter.error(
+ 'Unknown interpreted text role "%s".' % role,
+ line=lineno)
+ return ([self.problematic(rawsource, rawsource, msg)],
+ messages + [msg])
- def get_role_function(self, role, lineno):
- messages = []
- msg_text = []
- if role:
- name = role.lower()
- else:
- name = self.default_interpreted_role
- canonical = None
- try:
- canonical = self.language.roles[name]
- except AttributeError, error:
- msg_text.append('Problem retrieving role entry from language '
- 'module %r: %s.' % (self.language, error))
- except KeyError:
- msg_text.append('No role entry for "%s" in module "%s".'
- % (name, self.language.__name__))
- if not canonical:
- try:
- canonical = _fallback_language_module.roles[name]
- msg_text.append('Using English fallback for role "%s".'
- % name)
- except KeyError:
- msg_text.append('Trying "%s" as canonical role name.'
- % name)
- # Should be an English name, but just in case:
- canonical = name
- if msg_text:
- message = self.reporter.info('\n'.join(msg_text), line=lineno)
- messages.append(message)
- try:
- return self.interpreted_roles[canonical], canonical, messages
- except KeyError:
- raise UnknownInterpretedRoleError(messages)
-
def literal(self, match, lineno):
before, inlines, remaining, sysmessages, endstring = self.inline_obj(
match, lineno, self.patterns.literal, nodes.literal,
@@ -1014,8 +923,9 @@
def reference(self, match, lineno, anonymous=None):
referencename = match.group('refname')
refname = normalize_name(referencename)
- referencenode = nodes.reference(referencename + match.group('refend'),
- referencename)
+ referencenode = nodes.reference(
+ referencename + match.group('refend'), referencename,
+ name=whitespace_normalize_name(referencename))
if anonymous:
referencenode['anonymous'] = 1
self.document.note_anonymous_ref(referencenode)
@@ -1104,45 +1014,7 @@
'_': reference,
'__': anonymous_reference}
- def generic_interpreted_role(self, role, rawtext, text, lineno):
- try:
- role_class = self.generic_roles[role]
- except KeyError:
- msg = self.reporter.error('Unknown interpreted text role: "%s".'
- % role, line=lineno)
- prb = self.problematic(text, text, msg)
- return [prb], [msg]
- return [role_class(rawtext, text)], []
- def pep_reference_role(self, role, rawtext, text, lineno):
- try:
- pepnum = int(text)
- if pepnum < 0 or pepnum > 9999:
- raise ValueError
- except ValueError:
- msg = self.reporter.error(
- 'PEP number must be a number from 0 to 9999; "%s" is invalid.'
- % text, line=lineno)
- prb = self.problematic(text, text, msg)
- return [prb], [msg]
- ref = self.pep_url % pepnum
- return [nodes.reference(rawtext, 'PEP ' + text, refuri=ref)], []
-
- def rfc_reference_role(self, role, rawtext, text, lineno):
- try:
- rfcnum = int(text)
- if rfcnum <= 0:
- raise ValueError
- except ValueError:
- msg = self.reporter.error(
- 'RFC number must be a number greater than or equal to 1; '
- '"%s" is invalid.' % text, line=lineno)
- prb = self.problematic(text, text, msg)
- return [prb], [msg]
- ref = self.rfc_url % rfcnum
- return [nodes.reference(rawtext, 'RFC ' + text, refuri=ref)], []
-
-
class Body(RSTState):
"""
@@ -1472,15 +1344,15 @@
def field_marker(self, match, context, next_state):
"""Field list item."""
- fieldlist = nodes.field_list()
- self.parent += fieldlist
+ field_list = nodes.field_list()
+ self.parent += field_list
field, blank_finish = self.field(match)
- fieldlist += field
+ field_list += field
offset = self.state_machine.line_offset + 1 # next line
newline_offset, blank_finish = self.nested_list_parse(
self.state_machine.input_lines[offset:],
input_offset=self.state_machine.abs_line_offset() + 1,
- node=fieldlist, initial_state='FieldList',
+ node=field_list, initial_state='FieldList',
blank_finish=blank_finish)
self.goto_line(newline_offset)
if not blank_finish:
@@ -1492,14 +1364,15 @@
lineno = self.state_machine.abs_line_number()
indented, indent, line_offset, blank_finish = \
self.state_machine.get_first_known_indented(match.end())
- fieldnode = nodes.field()
- fieldnode.line = lineno
- fieldnode += nodes.field_name(name, name)
- fieldbody = nodes.field_body('\n'.join(indented))
- fieldnode += fieldbody
+ field_node = nodes.field()
+ field_node.line = lineno
+ name_nodes, name_messages = self.inline_text(name, lineno)
+ field_node += nodes.field_name(name, '', *name_nodes)
+ field_body = nodes.field_body('\n'.join(indented), *name_messages)
+ field_node += field_body
if indented:
- self.parse_field_body(indented, line_offset, fieldbody)
- return fieldnode, blank_finish
+ self.parse_field_body(indented, line_offset, field_body)
+ return field_node, blank_finish
def parse_field_marker(self, match):
"""Extract & return field name from a field marker match."""
@@ -1876,39 +1749,59 @@
raise MarkupError('malformed hyperlink target.', lineno)
del block[:blockindex]
block[0] = (block[0] + ' ')[targetmatch.end()-len(escaped)-1:].strip()
+ target = self.make_target(block, blocktext, lineno,
+ targetmatch.group('name'))
+ return [target], blank_finish
+
+ def make_target(self, block, block_text, lineno, target_name):
+ target_type, data = self.parse_target(block, block_text, lineno)
+ if target_type == 'refname':
+ target = nodes.target(block_text, '', refname=normalize_name(data))
+ target.indirect_reference_name = data
+ self.add_target(target_name, '', target, lineno)
+ self.document.note_indirect_target(target)
+ return target
+ elif target_type == 'refuri':
+ target = nodes.target(block_text, '')
+ self.add_target(target_name, data, target, lineno)
+ return target
+ else:
+ return data
+
+ def parse_target(self, block, block_text, lineno):
+ """
+ Determine the type of reference of a target.
+
+ :Return: A 2-tuple, one of:
+
+ - 'refname' and the indirect reference name
+ - 'refuri' and the URI
+ - 'malformed' and a system_message node
+ """
if block and block[-1].strip()[-1:] == '_': # possible indirect target
reference = ' '.join([line.strip() for line in block])
refname = self.is_reference(reference)
if refname:
- target = nodes.target(blocktext, '', refname=refname)
- target.line = lineno
- self.add_target(targetmatch.group('name'), '', target)
- self.document.note_indirect_target(target)
- return [target], blank_finish
- nodelist = []
+ return 'refname', refname
reference = ''.join([line.strip() for line in block])
- if reference.find(' ') != -1:
+ if reference.find(' ') == -1:
+ return 'refuri', unescape(reference)
+ else:
warning = self.reporter.warning(
'Hyperlink target contains whitespace. Perhaps a footnote '
'was intended?',
- nodes.literal_block(blocktext, blocktext), line=lineno)
- nodelist.append(warning)
- else:
- unescaped = unescape(reference)
- target = nodes.target(blocktext, '')
- target.line = lineno
- self.add_target(targetmatch.group('name'), unescaped, target)
- nodelist.append(target)
- return nodelist, blank_finish
+ nodes.literal_block(block_text, block_text), line=lineno)
+ return 'malformed', warning
def is_reference(self, reference):
match = self.explicit.patterns.reference.match(
- normalize_name(reference))
+ whitespace_normalize_name(reference))
if not match:
return None
return unescape(match.group('simple') or match.group('phrase'))
- def add_target(self, targetname, refuri, target):
+ def add_target(self, targetname, refuri, target, lineno):
+ target.line = lineno
if targetname:
name = normalize_name(unescape(targetname))
target['name'] = name
@@ -1988,17 +1881,18 @@
return [msg], blank_finish
def directive(self, match, **option_presets):
+ """Returns a 2-tuple: list of nodes, and a "blank finish" boolean."""
type_name = match.group(1)
directive_function, messages = directives.directive(
type_name, self.memo.language, self.document)
self.parent += messages
if directive_function:
- return self.parse_directive(
+ return self.run_directive(
directive_function, match, type_name, option_presets)
else:
return self.unknown_directive(type_name)
- def parse_directive(self, directive_fn, match, type_name, option_presets):
+ def run_directive(self, directive_fn, match, type_name, option_presets):
"""
Parse a directive then run its directive function.
@@ -2020,13 +1914,6 @@
Returns a 2-tuple: list of nodes, and a "blank finish" boolean.
"""
- arguments = []
- options = {}
- argument_spec = getattr(directive_fn, 'arguments', None)
- if argument_spec and argument_spec[:2] == (0, 0):
- argument_spec = None
- option_spec = getattr(directive_fn, 'options', None)
- content_spec = getattr(directive_fn, 'content', None)
lineno = self.state_machine.abs_line_number()
initial_line_offset = self.state_machine.line_offset
indented, indent, line_offset, blank_finish \
@@ -2034,6 +1921,30 @@
strip_top=0)
block_text = '\n'.join(self.state_machine.input_lines[
initial_line_offset : self.state_machine.line_offset + 1])
+ try:
+ arguments, options, content, content_offset = (
+ self.parse_directive_block(indented, line_offset,
+ directive_fn, option_presets))
+ except MarkupError, detail:
+ error = self.reporter.error(
+ 'Error in "%s" directive:\n%s.' % (type_name, detail),
+ nodes.literal_block(block_text, block_text), line=lineno)
+ return [error], blank_finish
+ result = directive_fn(type_name, arguments, options, content, lineno,
+ content_offset, block_text, self,
+ self.state_machine)
+ return (result,
+ blank_finish or self.state_machine.is_next_line_blank())
+
+ def parse_directive_block(self, indented, line_offset, directive_fn,
+ option_presets):
+ arguments = []
+ options = {}
+ argument_spec = getattr(directive_fn, 'arguments', None)
+ if argument_spec and argument_spec[:2] == (0, 0):
+ argument_spec = None
+ option_spec = getattr(directive_fn, 'options', None)
+ content_spec = getattr(directive_fn, 'content', None)
if indented and not indented[0].strip():
indented.trim_start()
line_offset += 1
@@ -2055,24 +1966,15 @@
while content and not content[0].strip():
content.trim_start()
content_offset += 1
- try:
- if option_spec:
- options, arg_block = self.parse_directive_options(
- option_presets, option_spec, arg_block)
- if argument_spec:
- arguments = self.parse_directive_arguments(argument_spec,
- arg_block)
- if content and not content_spec:
- raise MarkupError('no content permitted')
- except MarkupError, detail:
- error = self.reporter.error(
- 'Error in "%s" directive:\n%s.' % (type_name, detail),
- nodes.literal_block(block_text, block_text), line=lineno)
- return [error], blank_finish
- result = directive_fn(
- type_name, arguments, options, content, lineno, content_offset,
- block_text, self, self.state_machine)
- return result, blank_finish or self.state_machine.is_next_line_blank()
+ if option_spec:
+ options, arg_block = self.parse_directive_options(
+ option_presets, option_spec, arg_block)
+ if argument_spec:
+ arguments = self.parse_directive_arguments(
+ argument_spec, arg_block)
+ if content and not content_spec:
+ raise MarkupError('no content permitted')
+ return (arguments, options, content, content_offset)
def parse_directive_options(self, option_presets, option_spec, arg_block):
options = option_presets.copy()
@@ -2251,38 +2153,14 @@
return [], next_state, []
def anonymous_target(self, match):
+ lineno = self.state_machine.abs_line_number()
block, indent, offset, blank_finish \
= self.state_machine.get_first_known_indented(match.end(),
until_blank=1)
blocktext = match.string[:match.end()] + '\n'.join(block)
- if block and block[-1].strip()[-1:] == '_': # possible indirect target
- reference = escape2null(' '.join([line.strip()
- for line in block]))
- refname = self.is_reference(reference)
- if refname:
- target = nodes.target(blocktext, '', refname=refname,
- anonymous=1)
- self.document.note_anonymous_target(target)
- self.document.note_indirect_target(target)
- return [target], blank_finish
- nodelist = []
- reference = escape2null(''.join([line.strip() for line in block]))
- if reference.find(' ') != -1:
- lineno = self.state_machine.abs_line_number() - len(block) + 1
- warning = self.reporter.warning(
- 'Anonymous hyperlink target contains whitespace. Perhaps a '
- 'footnote was intended?',
- nodes.literal_block(blocktext, blocktext),
- line=lineno)
- nodelist.append(warning)
- else:
- target = nodes.target(blocktext, '', anonymous=1)
- if reference:
- unescaped = unescape(reference)
- target['refuri'] = unescaped
- self.document.note_anonymous_target(target)
- nodelist.append(target)
- return nodelist, blank_finish
+ block = [escape2null(line) for line in block]
+ target = self.make_target(block, blocktext, lineno, '')
+ return [target], blank_finish
def line(self, match, context, next_state):
"""Section title overline or transition marker."""
@@ -2660,20 +2538,29 @@
"""Return a list of nodes."""
indented, indent, offset, blank_finish = \
self.state_machine.get_indented()
- nodelist = []
while indented and not indented[-1].strip():
indented.trim_end()
- if indented:
- data = '\n'.join(indented)
- nodelist.append(nodes.literal_block(data, data))
- if not blank_finish:
- nodelist.append(self.unindent_warning('Literal block'))
- else:
- nodelist.append(self.reporter.warning(
- 'Literal block expected; none found.',
- line=self.state_machine.abs_line_number()))
+ if not indented:
+ return self.quoted_literal_block()
+ nodelist = []
+ data = '\n'.join(indented)
+ nodelist.append(nodes.literal_block(data, data))
+ if not blank_finish:
+ nodelist.append(self.unindent_warning('Literal block'))
return nodelist
+ def quoted_literal_block(self):
+ abs_line_offset = self.state_machine.abs_line_offset()
+ offset = self.state_machine.line_offset
+ parent_node = nodes.Element()
+ new_abs_offset = self.nested_parse(
+ self.state_machine.input_lines[offset:],
+ input_offset=abs_line_offset, node=parent_node, match_titles=0,
+ state_machine_kwargs={'state_classes': (QuotedLiteralBlock,),
+ 'initial_state': 'QuotedLiteralBlock'})
+ self.goto_line(new_abs_offset)
+ return parent_node.children
+
def definition_list_item(self, termline):
indented, indent, line_offset, blank_finish = \
self.state_machine.get_indented()
@@ -2687,8 +2574,8 @@
definitionlistitem += definition
if termline[0][-2:] == '::':
definition += self.reporter.info(
- 'Blank line missing before literal block? Interpreted as a '
- 'definition list item.', line=line_offset + 1)
+ 'Blank line missing before literal block (after the "::")? '
+ 'Interpreted as a definition list item.', line=line_offset+1)
self.nested_parse(indented, input_offset=line_offset, node=definition)
return definitionlistitem, blank_finish
@@ -2890,6 +2777,77 @@
raise statemachine.StateCorrection('Body', 'text')
+class QuotedLiteralBlock(RSTState):
+
+ """
+ Nested parse handler for quoted (unindented) literal blocks.
+
+ Special-purpose. Not for inclusion in `state_classes`.
+ """
+
+ patterns = {'initial_quoted': r'(%(nonalphanum7bit)s)' % Body.pats,
+ 'text': r''}
+ initial_transitions = ('initial_quoted', 'text')
+
+ def __init__(self, state_machine, debug=0):
+ RSTState.__init__(self, state_machine, debug)
+ self.messages = []
+ self.initial_lineno = None
+
+ def blank(self, match, context, next_state):
+ if context:
+ raise EOFError
+ else:
+ return context, next_state, []
+
+ def eof(self, context):
+ if context:
+ text = '\n'.join(context)
+ literal_block = nodes.literal_block(text, text)
+ literal_block.line = self.initial_lineno
+ self.parent += literal_block
+ else:
+ self.parent += self.reporter.warning(
+ 'Literal block expected; none found.',
+ line=self.state_machine.abs_line_number())
+ self.state_machine.previous_line()
+ self.parent += self.messages
+ return []
+
+ def indent(self, match, context, next_state):
+ assert context, ('QuotedLiteralBlock.indent: context should not '
+ 'be empty!')
+ self.messages.append(
+ self.reporter.error('Unexpected indentation.',
+ line=self.state_machine.abs_line_number()))
+ self.state_machine.previous_line()
+ raise EOFError
+
+ def initial_quoted(self, match, context, next_state):
+ """Match arbitrary quote character on the first line only."""
+ self.remove_transition('initial_quoted')
+ quote = match.string[0]
+ pattern = re.compile(re.escape(quote))
+ # New transition matches consistent quotes only:
+ self.add_transition('quoted',
+ (pattern, self.quoted, self.__class__.__name__))
+ self.initial_lineno = self.state_machine.abs_line_number()
+ return [match.string], next_state, []
+
+ def quoted(self, match, context, next_state):
+ """Match consistent quotes on subsequent lines."""
+ context.append(match.string)
+ return context, next_state, []
+
+ def text(self, match, context, next_state):
+ if context:
+ self.messages.append(
+ self.reporter.error('Inconsistent literal block quoting.',
+ line=self.state_machine.abs_line_number()))
+ self.state_machine.previous_line()
+ raise EOFError
+
+
state_classes = (Body, BulletList, DefinitionList, EnumeratedList, FieldList,
OptionList, ExtensionOptions, Explicit, Text, Definition,
Line, SubstitutionDef, RFC2822Body, RFC2822List)
Modified: Zope/trunk/lib/python/docutils/parsers/rst/tableparser.py
===================================================================
--- Zope/trunk/lib/python/docutils/parsers/rst/tableparser.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/parsers/rst/tableparser.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:07:46 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:47 $
# Copyright: This module has been placed in the public domain.
"""
Modified: Zope/trunk/lib/python/docutils/readers/__init__.py
===================================================================
--- Zope/trunk/lib/python/docutils/readers/__init__.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/readers/__init__.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Authors: David Goodger; Ueli Schlaepfer
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:08 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:52 $
# Copyright: This module has been placed in the public domain.
"""
Modified: Zope/trunk/lib/python/docutils/readers/pep.py
===================================================================
--- Zope/trunk/lib/python/docutils/readers/pep.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/readers/pep.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:08 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:52 $
# Copyright: This module has been placed in the public domain.
"""
Modified: Zope/trunk/lib/python/docutils/readers/python/__init__.py
===================================================================
--- Zope/trunk/lib/python/docutils/readers/python/__init__.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/readers/python/__init__.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.3 $
-# Date: $Date: 2003/11/30 15:06:08 $
+# Revision: $Revision: 1.3.2.1.8.1 $
+# Date: $Date: 2004/05/12 19:57:53 $
# Copyright: This module has been placed in the public domain.
"""
@@ -13,9 +13,117 @@
import sys
import docutils.readers
+from docutils.readers.python import moduleparser
+from docutils import parsers
+from docutils import nodes
+from docutils.readers.python import pynodes
+from docutils import readers
-
class Reader(docutils.readers.Reader):
config_section = 'python reader'
config_section_dependencies = ('readers',)
+
+ default_parser = 'restructuredtext'
+
+ def parse(self):
+ """Parse `self.input` into a document tree."""
+ self.document = document = self.new_document()
+ module_section = moduleparser.parse_module(self.input,
+ self.source.source_path)
+ module_section.walk(DocformatVisitor(self.document))
+ visitor = DocstringFormattingVisitor(
+ document=document,
+ default_parser=self.default_parser)
+ module_section.walk(visitor)
+ self.document.append(module_section)
+
+
+class DocformatVisitor(nodes.SparseNodeVisitor):
+
+ """
+ This sets docformat attributes in a module. Wherever an assignment
+ to __docformat__ is found, we look for the enclosing scope -- a class,
+ a module, or a function -- and set the docformat attribute there.
+
+ We can't do this during the DocstringFormattingVisitor walking,
+ because __docformat__ may appear below a docstring in that format
+ (typically below the module docstring).
+ """
+
+ def visit_attribute(self, node):
+ assert isinstance(node[0], pynodes.object_name)
+ name = node[0][0].data
+ if name != '__docformat__':
+ return
+ value = None
+ for child in children:
+ if isinstance(child, pynodes.expression_value):
+ value = child[0].data
+ break
+ assert value.startswith("'") or value.startswith('"'), "__docformat__ must be assigned a string literal (not %s); line: %s" % (value, node['lineno'])
+ name = name[1:-1]
+ looking_in = node.parent
+ while not isinstance(looking_in, (pynodes.module_section,
+ pynodes.function_section,
+ pynodes.class_section)):
+ looking_in = looking_in.parent
+ looking_in['docformat'] = name
+
+
+class DocstringFormattingVisitor(nodes.SparseNodeVisitor):
+
+ def __init__(self, document, default_parser):
+ self.document = document
+ self.default_parser = default_parser
+ self.parsers = {}
+
+ def visit_docstring(self, node):
+ text = node[0].data
+ docformat = self.find_docformat(node)
+ del node[0]
+ node['docformat'] = docformat
+ parser = self.get_parser(docformat)
+ parser.parse(text, self.document)
+ for child in self.document.get_children():
+ node.append(child)
+ self.document.current_source = self.document.current_line = None
+ del self.document[:]
+
+ def get_parser(self, parser_name):
+ """
+ Get a parser based on its name. We reuse parsers during this
+ visitation, so parser instances are cached.
+ """
+ parser_name = parsers._parser_aliases.get(parser_name, parser_name)
+ if not self.parsers.has_key(parser_name):
+ cls = parsers.get_parser_class(parser_name)
+ self.parsers[parser_name] = cls()
+ return self.parsers[parser_name]
+
+ def find_docformat(self, node):
+ """
+ Find the __docformat__ closest to this node (i.e., look in the
+ class or module)
+ """
+ while node:
+ if node.get('docformat'):
+ return node['docformat']
+ node = node.parent
+ return self.default_parser
+
+
+if __name__ == '__main__':
+ try:
+ import locale
+ locale.setlocale(locale.LC_ALL, '')
+ except:
+ pass
+
+ from docutils.core import publish_cmdline, default_description
+
+ description = ('Generates pseudo-XML from Python modules '
+ '(for testing purposes). ' + default_description)
+
+ publish_cmdline(description=description,
+ reader=Reader())
Modified: Zope/trunk/lib/python/docutils/readers/python/moduleparser.py
===================================================================
--- Zope/trunk/lib/python/docutils/readers/python/moduleparser.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/readers/python/moduleparser.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,17 +1,16 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.3 $
-# Date: $Date: 2003/11/30 15:06:08 $
+# Revision: $Revision: 1.3.2.1.8.1 $
+# Date: $Date: 2004/05/12 19:57:53 $
# Copyright: This module has been placed in the public domain.
"""
Parser for Python modules.
-The `parse_module()` function takes a module's text and file name, runs it
-through the module parser (using compiler.py and tokenize.py) and produces a
-"module documentation tree": a high-level AST full of nodes that are
-interesting from an auto-documentation standpoint. For example, given this
-module (x.py)::
+The `parse_module()` function takes a module's text and file name,
+runs it through the module parser (using compiler.py and tokenize.py)
+and produces a parse tree of the source code, using the nodes as found
+in pynodes.py. For example, given this module (x.py)::
# comment
@@ -50,69 +49,95 @@
The module parser will produce this module documentation tree::
- <Module filename="test data">
- <Comment lineno=1>
- comment
- <Docstring>
+ <module_section filename="test data">
+ <docstring>
Docstring
- <Docstring lineno="5">
+ <docstring lineno="5">
Additional docstring
- <Attribute lineno="7" name="__docformat__">
- <Expression lineno="7">
+ <attribute lineno="7">
+ <object_name>
+ __docformat__
+ <expression_value lineno="7">
'reStructuredText'
- <Attribute lineno="9" name="a">
- <Expression lineno="9">
+ <attribute lineno="9">
+ <object_name>
+ a
+ <expression_value lineno="9">
1
- <Docstring lineno="10">
+ <docstring lineno="10">
Attribute docstring
- <Class bases="Super" lineno="12" name="C">
- <Docstring lineno="12">
+ <class_section lineno="12">
+ <object_name>
+ C
+ <class_base>
+ Super
+ <docstring lineno="12">
C's docstring
- <Attribute lineno="16" name="class_attribute">
- <Expression lineno="16">
+ <attribute lineno="16">
+ <object_name>
+ class_attribute
+ <expression_value lineno="16">
1
- <Docstring lineno="17">
+ <docstring lineno="17">
class_attribute's docstring
- <Method lineno="19" name="__init__">
- <Docstring lineno="19">
+ <method_section lineno="19">
+ <object_name>
+ __init__
+ <docstring lineno="19">
__init__'s docstring
- <ParameterList lineno="19">
- <Parameter lineno="19" name="self">
- <Parameter lineno="19" name="text">
- <Default lineno="19">
+ <parameter_list lineno="19">
+ <parameter lineno="19">
+ <object_name>
+ self
+ <parameter lineno="19">
+ <object_name>
+ text
+ <parameter_default lineno="19">
None
- <Attribute lineno="22" name="self.instance_attribute">
- <Expression lineno="22">
+ <attribute lineno="22">
+ <object_name>
+ self.instance_attribute
+ <expression_value lineno="22">
(text * 7 + ' whaddyaknow')
- <Docstring lineno="24">
+ <docstring lineno="24">
instance_attribute's docstring
- <Function lineno="27" name="f">
- <Docstring lineno="27">
+ <function_section lineno="27">
+ <object_name>
+ f
+ <docstring lineno="27">
f's docstring
- <ParameterList lineno="27">
- <Parameter lineno="27" name="x">
- <Comment>
+ <parameter_list lineno="27">
+ <parameter lineno="27">
+ <object_name>
+ x
+ <comment>
# parameter x
- <Parameter lineno="27" name="y">
- <Default lineno="27">
+ <parameter lineno="27">
+ <object_name>
+ y
+ <parameter_default lineno="27">
a * 5
- <Comment>
+ <comment>
# parameter y
- <ExcessPositionalArguments lineno="27" name="args">
- <Comment>
+ <parameter excess_positional="1" lineno="27">
+ <object_name>
+ args
+ <comment>
# parameter args
- <Attribute lineno="33" name="f.function_attribute">
- <Expression lineno="33">
+ <attribute lineno="33">
+ <object_name>
+ f.function_attribute
+ <expression_value lineno="33">
1
- <Docstring lineno="34">
+ <docstring lineno="34">
f.function_attribute's docstring
(Comments are not implemented yet.)
compiler.parse() provides most of what's needed for this doctree, and
-"tokenize" can be used to get the rest. We can determine the line number from
-the compiler.parse() AST, and the TokenParser.rhs(lineno) method provides the
-rest.
+"tokenize" can be used to get the rest. We can determine the line
+number from the compiler.parse() AST, and the TokenParser.rhs(lineno)
+method provides the rest.
The Docutils Python reader component will transform this module doctree into a
Python-specific Docutils doctree, and then a `stylist transform`_ will
@@ -190,6 +215,8 @@
from compiler.consts import OP_ASSIGN
from compiler.visitor import ASTVisitor
from types import StringType, UnicodeType, TupleType
+from docutils.readers.python import pynodes
+from docutils.nodes import Text
def parse_module(module_text, filename):
@@ -200,168 +227,6 @@
compiler.walk(ast, visitor, walker=visitor)
return visitor.module
-
-class Node:
-
- """
- Base class for module documentation tree nodes.
- """
-
- def __init__(self, node):
- self.children = []
- """List of child nodes."""
-
- self.lineno = node.lineno
- """Line number of this node (or ``None``)."""
-
- def __str__(self, indent=' ', level=0):
- return ''.join(['%s%s\n' % (indent * level, repr(self))] +
- [child.__str__(indent, level+1)
- for child in self.children])
-
- def __repr__(self):
- parts = [self.__class__.__name__]
- for name, value in self.attlist():
- parts.append('%s="%s"' % (name, value))
- return '<%s>' % ' '.join(parts)
-
- def attlist(self, **atts):
- if self.lineno is not None:
- atts['lineno'] = self.lineno
- attlist = atts.items()
- attlist.sort()
- return attlist
-
- def append(self, node):
- self.children.append(node)
-
- def extend(self, node_list):
- self.children.extend(node_list)
-
-
-class TextNode(Node):
-
- def __init__(self, node, text):
- Node.__init__(self, node)
- self.text = trim_docstring(text)
-
- def __str__(self, indent=' ', level=0):
- prefix = indent * (level + 1)
- text = '\n'.join([prefix + line for line in self.text.splitlines()])
- return Node.__str__(self, indent, level) + text + '\n'
-
-
-class Module(Node):
-
- def __init__(self, node, filename):
- Node.__init__(self, node)
- self.filename = filename
-
- def attlist(self):
- return Node.attlist(self, filename=self.filename)
-
-
-class Docstring(TextNode): pass
-
-
-class Comment(TextNode): pass
-
-
-class Import(Node):
-
- def __init__(self, node, names, from_name=None):
- Node.__init__(self, node)
- self.names = names
- self.from_name = from_name
-
- def __str__(self, indent=' ', level=0):
- prefix = indent * (level + 1)
- lines = []
- for name, as in self.names:
- if as:
- lines.append('%s%s as %s' % (prefix, name, as))
- else:
- lines.append('%s%s' % (prefix, name))
- text = '\n'.join(lines)
- return Node.__str__(self, indent, level) + text + '\n'
-
- def attlist(self):
- if self.from_name:
- atts = {'from': self.from_name}
- else:
- atts = {}
- return Node.attlist(self, **atts)
-
-
-class Attribute(Node):
-
- def __init__(self, node, name):
- Node.__init__(self, node)
- self.name = name
-
- def attlist(self):
- return Node.attlist(self, name=self.name)
-
-
-class AttributeTuple(Node):
-
- def __init__(self, node, names):
- Node.__init__(self, node)
- self.names = names
-
- def attlist(self):
- return Node.attlist(self, names=' '.join(self.names))
-
-
-class Expression(TextNode):
-
- def __str__(self, indent=' ', level=0):
- prefix = indent * (level + 1)
- return '%s%s%s\n' % (Node.__str__(self, indent, level),
- prefix, self.text.encode('unicode-escape'))
-
-
-class Function(Attribute): pass
-
-
-class ParameterList(Node): pass
-
-
-class Parameter(Attribute): pass
-
-
-class ParameterTuple(AttributeTuple):
-
- def attlist(self):
- return Node.attlist(self, names=normalize_parameter_name(self.names))
-
-
-class ExcessPositionalArguments(Parameter): pass
-
-
-class ExcessKeywordArguments(Parameter): pass
-
-
-class Default(Expression): pass
-
-
-class Class(Node):
-
- def __init__(self, node, name, bases=None):
- Node.__init__(self, node)
- self.name = name
- self.bases = bases or []
-
- def attlist(self):
- atts = {'name': self.name}
- if self.bases:
- atts['bases'] = ' '.join(self.bases)
- return Node.attlist(self, **atts)
-
-
-class Method(Function): pass
-
-
class BaseVisitor(ASTVisitor):
def __init__(self, token_parser):
@@ -389,7 +254,7 @@
def visitConst(self, node):
if self.documentable:
if type(node.value) in (StringType, UnicodeType):
- self.documentable.append(Docstring(node, node.value))
+ self.documentable.append(make_docstring(node.value, node.lineno))
else:
self.documentable = None
@@ -418,25 +283,28 @@
self.module = None
def visitModule(self, node):
- self.module = module = Module(node, self.filename)
- if node.doc is not None:
- module.append(Docstring(node, node.doc))
+ self.module = module = pynodes.module_section()
+ module['filename'] = self.filename
+ append_docstring(module, node.doc, node.lineno)
self.context.append(module)
self.documentable = module
self.visit(node.node)
self.context.pop()
def visitImport(self, node):
- self.context[-1].append(Import(node, node.names))
+ self.context[-1] += make_import_group(names=node.names,
+ lineno=node.lineno)
self.documentable = None
def visitFrom(self, node):
self.context[-1].append(
- Import(node, node.names, from_name=node.modname))
+ make_import_group(names=node.names, from_name=node.modname,
+ lineno=node.lineno))
self.documentable = None
def visitFunction(self, node):
- visitor = FunctionVisitor(self.token_parser)
+ visitor = FunctionVisitor(self.token_parser,
+ function_class=pynodes.function_section)
compiler.walk(node, visitor, walker=visitor)
self.context[-1].append(visitor.function)
@@ -450,29 +318,32 @@
def __init__(self, token_parser):
BaseVisitor.__init__(self, token_parser)
- self.attributes = []
+ self.attributes = pynodes.class_attribute_section()
def visitAssign(self, node):
# Don't visit the expression itself, just the attribute nodes:
for child in node.nodes:
self.dispatch(child)
expression_text = self.token_parser.rhs(node.lineno)
- expression = Expression(node, expression_text)
+ expression = pynodes.expression_value()
+ expression.append(Text(expression_text))
for attribute in self.attributes:
attribute.append(expression)
def visitAssName(self, node):
- self.attributes.append(Attribute(node, node.name))
+ self.attributes.append(make_attribute(node.name,
+ lineno=node.lineno))
def visitAssTuple(self, node):
attributes = self.attributes
self.attributes = []
self.default_visit(node)
- names = [attribute.name for attribute in self.attributes]
- att_tuple = AttributeTuple(node, names)
- att_tuple.lineno = self.attributes[0].lineno
+ n = pynodes.attribute_tuple()
+ n.extend(self.attributes)
+ n['lineno'] = self.attributes[0]['lineno']
+ attributes.append(n)
self.attributes = attributes
- self.attributes.append(att_tuple)
+ #self.attributes.append(att_tuple)
def visitAssAttr(self, node):
self.default_visit(node, node.attrname)
@@ -481,23 +352,29 @@
self.default_visit(node, node.attrname + '.' + suffix)
def visitName(self, node, suffix):
- self.attributes.append(Attribute(node, node.name + '.' + suffix))
+ self.attributes.append(make_attribute(node.name + '.' + suffix,
+ lineno=node.lineno))
class FunctionVisitor(DocstringVisitor):
in_function = 0
- function_class = Function
+ def __init__(self, token_parser, function_class):
+ DocstringVisitor.__init__(self, token_parser)
+ self.function_class = function_class
+
def visitFunction(self, node):
if self.in_function:
self.documentable = None
# Don't bother with nested function definitions.
return
self.in_function = 1
- self.function = function = self.function_class(node, node.name)
- if node.doc is not None:
- function.append(Docstring(node, node.doc))
+ self.function = function = make_function_like_section(
+ name=node.name,
+ lineno=node.lineno,
+ doc=node.doc,
+ function_class=self.function_class)
self.context.append(function)
self.documentable = function
self.parse_parameter_list(node)
@@ -509,10 +386,11 @@
special = []
argnames = list(node.argnames)
if node.kwargs:
- special.append(ExcessKeywordArguments(node, argnames[-1]))
+ special.append(make_parameter(argnames[-1], excess_keyword=1))
argnames.pop()
if node.varargs:
- special.append(ExcessPositionalArguments(node, argnames[-1]))
+ special.append(make_parameter(argnames[-1],
+ excess_positional=1))
argnames.pop()
defaults = list(node.defaults)
defaults = [None] * (len(argnames) - len(defaults)) + defaults
@@ -521,17 +399,21 @@
#print >>sys.stderr, function_parameters
for argname, default in zip(argnames, defaults):
if type(argname) is TupleType:
- parameter = ParameterTuple(node, argname)
+ parameter = pynodes.parameter_tuple()
+ for tuplearg in argname:
+ parameter.append(make_parameter(tuplearg))
argname = normalize_parameter_name(argname)
else:
- parameter = Parameter(node, argname)
+ parameter = make_parameter(argname)
if default:
- parameter.append(Default(node, function_parameters[argname]))
+ n_default = pynodes.parameter_default()
+ n_default.append(Text(function_parameters[argname]))
+ parameter.append(n_default)
parameters.append(parameter)
if parameters or special:
special.reverse()
parameters.extend(special)
- parameter_list = ParameterList(node)
+ parameter_list = pynodes.parameter_list()
parameter_list.extend(parameters)
self.function.append(parameter_list)
@@ -554,9 +436,9 @@
#pdb.set_trace()
for base in node.bases:
self.visit(base)
- self.klass = klass = Class(node, node.name, self.bases)
- if node.doc is not None:
- klass.append(Docstring(node, node.doc))
+ self.klass = klass = make_class_section(node.name, self.bases,
+ doc=node.doc,
+ lineno=node.lineno)
self.context.append(klass)
self.documentable = klass
self.visit(node.code)
@@ -578,21 +460,19 @@
def visitFunction(self, node):
if node.name == '__init__':
- visitor = InitMethodVisitor(self.token_parser)
+ visitor = InitMethodVisitor(self.token_parser,
+ function_class=pynodes.method_section)
+ compiler.walk(node, visitor, walker=visitor)
else:
- visitor = MethodVisitor(self.token_parser)
- compiler.walk(node, visitor, walker=visitor)
+ visitor = FunctionVisitor(self.token_parser,
+ function_class=pynodes.method_section)
+ compiler.walk(node, visitor, walker=visitor)
self.context[-1].append(visitor.function)
-class MethodVisitor(FunctionVisitor):
+class InitMethodVisitor(FunctionVisitor, AssignmentVisitor): pass
- function_class = Method
-
-class InitMethodVisitor(MethodVisitor, AssignmentVisitor): pass
-
-
class TokenParser:
def __init__(self, text):
@@ -744,6 +624,85 @@
return parameters
+def make_docstring(doc, lineno):
+ n = pynodes.docstring()
+ if lineno:
+ # Really, only module docstrings don't have a line
+ # (@@: but maybe they should)
+ n['lineno'] = lineno
+ n.append(Text(doc))
+ return n
+
+def append_docstring(node, doc, lineno):
+ if doc:
+ node.append(make_docstring(doc, lineno))
+
+def make_class_section(name, bases, lineno, doc):
+ n = pynodes.class_section()
+ n['lineno'] = lineno
+ n.append(make_object_name(name))
+ for base in bases:
+ b = pynodes.class_base()
+ b.append(make_object_name(base))
+ n.append(b)
+ append_docstring(n, doc, lineno)
+ return n
+
+def make_object_name(name):
+ n = pynodes.object_name()
+ n.append(Text(name))
+ return n
+
+def make_function_like_section(name, lineno, doc, function_class):
+ n = function_class()
+ n['lineno'] = lineno
+ n.append(make_object_name(name))
+ append_docstring(n, doc, lineno)
+ return n
+
+def make_import_group(names, lineno, from_name=None):
+ n = pynodes.import_group()
+ n['lineno'] = lineno
+ if from_name:
+ n_from = pynodes.import_from()
+ n_from.append(Text(from_name))
+ n.append(n_from)
+ for name, alias in names:
+ n_name = pynodes.import_name()
+ n_name.append(Text(name))
+ if alias:
+ n_alias = pynodes.import_alias()
+ n_alias.append(Text(alias))
+ n_name.append(n_alias)
+ n.append(n_name)
+ return n
+
+def make_class_attribute(name, lineno):
+ n = pynodes.class_attribute()
+ n['lineno'] = lineno
+ n.append(Text(name))
+ return n
+
+def make_attribute(name, lineno):
+ n = pynodes.attribute()
+ n['lineno'] = lineno
+ n.append(make_object_name(name))
+ return n
+
+def make_parameter(name, excess_keyword=0, excess_positional=0):
+ """
+ excess_keyword and excess_positional must be either 1 or 0, and
+ not both of them can be 1.
+ """
+ n = pynodes.parameter()
+ n.append(make_object_name(name))
+ assert not excess_keyword or not excess_positional
+ if excess_keyword:
+ n['excess_keyword'] = 1
+ if excess_positional:
+ n['excess_positional'] = 1
+ return n
+
def trim_docstring(text):
"""
Trim indentation and blank lines from docstring text & return it.
@@ -782,3 +741,18 @@
return '(%s)' % ', '.join([normalize_parameter_name(n) for n in name])
else:
return name
+
+if __name__ == '__main__':
+ import sys
+ args = sys.argv[1:]
+ if args[0] == '-v':
+ filename = args[1]
+ module_text = open(filename).read()
+ ast = compiler.parse(module_text)
+ visitor = compiler.visitor.ExampleASTVisitor()
+ compiler.walk(ast, visitor, walker=visitor, verbose=1)
+ else:
+ filename = args[0]
+ content = open(filename).read()
+ print parse_module(content, filename).pformat()
+
Added: Zope/trunk/lib/python/docutils/readers/python/pynodes.py
===================================================================
--- Zope/trunk/lib/python/docutils/readers/python/pynodes.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/readers/python/pynodes.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -0,0 +1,87 @@
+#! /usr/bin/env python
+
+"""
+:Author: David Goodger
+:Contact: goodger at users.sourceforge.net
+:Revision: $Revision: 1.1.2.1 $
+:Date: $Date: 2004/05/12 19:57:53 $
+:Copyright: This module has been placed in the public domain.
+
+"""
+
+from docutils import nodes
+from docutils.nodes import Element, TextElement, Structural, Inline, Part, \
+ Text
+import types
+
+# This is the parent class of all the other pynode classes:
+class PythonStructural(Structural): pass
+
+# =====================
+# Structural Elements
+# =====================
+
+class module_section(PythonStructural, Element): pass
+class class_section(PythonStructural, Element): pass
+class class_base(PythonStructural, Element): pass
+class method_section(PythonStructural, Element): pass
+class attribute(PythonStructural, Element): pass
+class function_section(PythonStructural, Element): pass
+class class_attribute_section(PythonStructural, Element): pass
+class class_attribute(PythonStructural, Element): pass
+class expression_value(PythonStructural, Element): pass
+class attribute(PythonStructural, Element): pass
+
+# Structural Support Elements
+# ---------------------------
+
+class parameter_list(PythonStructural, Element): pass
+class parameter_tuple(PythonStructural, Element): pass
+class parameter_default(PythonStructural, TextElement): pass
+class import_group(PythonStructural, TextElement): pass
+class import_from(PythonStructural, TextElement): pass
+class import_name(PythonStructural, TextElement): pass
+class import_alias(PythonStructural, TextElement): pass
+class docstring(PythonStructural, Element): pass
+
+# =================
+# Inline Elements
+# =================
+
+# These elements cannot become references until the second
+# pass. Initially, we'll use "reference" or "name".
+
+class object_name(PythonStructural, TextElement): pass
+class parameter_list(PythonStructural, TextElement): pass
+class parameter(PythonStructural, TextElement): pass
+class parameter_default(PythonStructural, TextElement): pass
+class class_attribute(PythonStructural, TextElement): pass
+class attribute_tuple(PythonStructural, TextElement): pass
+
+# =================
+# Unused Elements
+# =================
+
+# These were part of the model, and maybe should be in the future, but
+# aren't now.
+#class package_section(PythonStructural, Element): pass
+#class module_attribute_section(PythonStructural, Element): pass
+#class instance_attribute_section(PythonStructural, Element): pass
+#class module_attribute(PythonStructural, TextElement): pass
+#class instance_attribute(PythonStructural, TextElement): pass
+#class exception_class(PythonStructural, TextElement): pass
+#class warning_class(PythonStructural, TextElement): pass
+
+
+# Collect all the classes we've written above
+def install_node_class_names():
+ node_class_names = []
+ for name, var in globals().items():
+ if (type(var) is types.ClassType
+ and issubclass(var, PythonStructural) \
+ and name.lower() == name):
+ node_class_names.append(var.tagname or name)
+ # Register the new node names with GenericNodeVisitor and
+ # SpecificNodeVisitor:
+ nodes._add_node_class_names(node_class_names)
+install_node_class_names()
Modified: Zope/trunk/lib/python/docutils/readers/standalone.py
===================================================================
--- Zope/trunk/lib/python/docutils/readers/standalone.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/readers/standalone.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:08 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:52 $
# Copyright: This module has been placed in the public domain.
"""
@@ -14,7 +14,6 @@
import sys
from docutils import frontend, readers
from docutils.transforms import frontmatter, references
-from docutils.parsers.rst import Parser
class Reader(readers.Reader):
Modified: Zope/trunk/lib/python/docutils/statemachine.py
===================================================================
--- Zope/trunk/lib/python/docutils/statemachine.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/statemachine.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:04 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:39 $
# Copyright: This module has been placed in the public domain.
"""
Modified: Zope/trunk/lib/python/docutils/transforms/__init__.py
===================================================================
--- Zope/trunk/lib/python/docutils/transforms/__init__.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/transforms/__init__.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Authors: David Goodger, Ueli Schlaepfer
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:09 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:55 $
# Copyright: This module has been placed in the public domain.
"""
@@ -59,6 +59,7 @@
self.language = languages.get_language(
document.settings.language_code)
"""Language module local to this document."""
+
def apply(self):
"""Override to apply the transform to the document tree."""
@@ -76,7 +77,8 @@
default_transforms = (universal.Decorations,
universal.FinalChecks,
- universal.Messages)
+ universal.Messages,
+ universal.FilterMessages)
"""These transforms are applied to all document trees."""
def __init__(self, document):
@@ -84,6 +86,9 @@
"""List of transforms to apply. Each item is a 3-tuple:
``(priority string, transform class, pending node or None)``."""
+ self.unknown_reference_resolvers = []
+ """List of hook functions which assist in resolving references"""
+
self.document = document
"""The `nodes.document` object this Transformer is attached to."""
@@ -149,7 +154,17 @@
self.add_transforms(component.default_transforms)
self.components[component.component_type] = component
self.sorted = 0
+ # Setup all of the reference resolvers for this transformer. Each
+ # component of this transformer is able to register its own helper
+ # functions to help resolve references.
+ unknown_reference_resolvers = []
+ for i in components:
+ unknown_reference_resolvers.extend(i.unknown_reference_resolvers)
+ decorated_list = [(f.priority, f) for f in unknown_reference_resolvers]
+ decorated_list.sort()
+ self.unknown_reference_resolvers.extend([f[1] for f in decorated_list])
+
def apply_transforms(self):
"""Apply all of the stored transforms, in priority order."""
self.document.reporter.attach_observer(
Modified: Zope/trunk/lib/python/docutils/transforms/components.py
===================================================================
--- Zope/trunk/lib/python/docutils/transforms/components.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/transforms/components.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:09 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:55 $
# Copyright: This module has been placed in the public domain.
"""
Modified: Zope/trunk/lib/python/docutils/transforms/frontmatter.py
===================================================================
--- Zope/trunk/lib/python/docutils/transforms/frontmatter.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/transforms/frontmatter.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Authors: David Goodger, Ueli Schlaepfer
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:09 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:55 $
# Copyright: This module has been placed in the public domain.
"""
@@ -334,10 +334,10 @@
return 1
rcs_keyword_substitutions = [
- (re.compile(r'\$' r'Date: (\d\d\d\d)/(\d\d)/(\d\d) [\d:]+ \$$',
+ (re.compile(r'\$' r'Date: (\d\d\d\d)/(\d\d)/(\d\d) [\d:]+ \$',
re.IGNORECASE), r'\1-\2-\3'),
- (re.compile(r'\$' r'RCSfile: (.+),v \$$', re.IGNORECASE), r'\1'),
- (re.compile(r'\$[a-zA-Z]+: (.+) \$$'), r'\1'),]
+ (re.compile(r'\$' r'RCSfile: (.+),v \$', re.IGNORECASE), r'\1'),
+ (re.compile(r'\$[a-zA-Z]+: (.+) \$'), r'\1'),]
def extract_authors(self, field, name, docinfo):
try:
Modified: Zope/trunk/lib/python/docutils/transforms/misc.py
===================================================================
--- Zope/trunk/lib/python/docutils/transforms/misc.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/transforms/misc.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:09 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:55 $
# Copyright: This module has been placed in the public domain.
"""
Modified: Zope/trunk/lib/python/docutils/transforms/parts.py
===================================================================
--- Zope/trunk/lib/python/docutils/transforms/parts.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/transforms/parts.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Authors: David Goodger, Ueli Schlaepfer, Dmitry Jemerov
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:09 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:55 $
# Copyright: This module has been placed in the public domain.
"""
@@ -34,7 +34,8 @@
def apply(self):
self.maxdepth = self.startnode.details.get('depth', sys.maxint)
self.startnode.parent.remove(self.startnode)
- self.update_section_numbers(self.document)
+ if self.document.settings.sectnum_xform:
+ self.update_section_numbers(self.document)
def update_section_numbers(self, node, prefix=(), depth=0):
depth += 1
@@ -58,11 +59,11 @@
"""
This transform generates a table of contents from the entire document tree
or from a single branch. It locates "section" elements and builds them
- into a nested bullet list, which is placed within a "topic". A title is
- either explicitly specified, taken from the appropriate language module,
- or omitted (local table of contents). The depth may be specified.
- Two-way references between the table of contents and section titles are
- generated (requires Writer support).
+ into a nested bullet list, which is placed within a "topic" created by the
+ contents directive. A title is either explicitly specified, taken from
+ the appropriate language module, or omitted (local table of contents).
+ The depth may be specified. Two-way references between the table of
+ contents and section titles are generated (requires Writer support).
This transform requires a startnode, which which contains generation
options and provides the location for the generated table of contents (the
@@ -72,41 +73,26 @@
default_priority = 720
def apply(self):
- topic = nodes.topic(CLASS='contents')
details = self.startnode.details
- if details.has_key('class'):
- topic.set_class(details['class'])
- title = details['title']
if details.has_key('local'):
- startnode = self.startnode.parent
+ startnode = self.startnode.parent.parent
# @@@ generate an error if the startnode (directive) not at
# section/document top-level? Drag it up until it is?
while not isinstance(startnode, nodes.Structural):
startnode = startnode.parent
else:
startnode = self.document
- if not title:
- title = nodes.title('', self.language.labels['contents'])
- if title:
- name = title.astext()
- topic += title
- else:
- name = self.language.labels['contents']
- name = nodes.fully_normalize_name(name)
- if not self.document.has_name(name):
- topic['name'] = name
- self.document.note_implicit_target(topic)
- self.toc_id = topic['id']
+
+ self.toc_id = self.startnode.parent['id']
if details.has_key('backlinks'):
self.backlinks = details['backlinks']
else:
self.backlinks = self.document.settings.toc_backlinks
contents = self.build_contents(startnode)
if len(contents):
- topic += contents
- self.startnode.parent.replace(self.startnode, topic)
+ self.startnode.parent.replace(self.startnode, contents)
else:
- self.startnode.parent.remove(self.startnode)
+ self.startnode.parent.parent.remove(self.startnode.parent)
def build_contents(self, node, level=0):
level += 1
Modified: Zope/trunk/lib/python/docutils/transforms/peps.py
===================================================================
--- Zope/trunk/lib/python/docutils/transforms/peps.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/transforms/peps.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:09 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:55 $
# Copyright: This module has been placed in the public domain.
"""
@@ -19,7 +19,7 @@
import os
import re
import time
-from docutils import nodes, utils
+from docutils import nodes, utils, languages
from docutils import ApplicationError, DataError
from docutils.transforms import Transform, TransformError
from docutils.transforms import parts, references, misc
@@ -137,15 +137,24 @@
class Contents(Transform):
"""
- Insert a table of contents transform placeholder into the document after
- the RFC 2822 header.
+ Insert an empty table of contents topic and a transform placeholder into
+ the document after the RFC 2822 header.
"""
default_priority = 380
def apply(self):
- pending = nodes.pending(parts.Contents, {'title': None})
- self.document.insert(1, pending)
+ language = languages.get_language(self.document.settings.language_code)
+ name = language.labels['contents']
+ title = nodes.title('', name)
+ topic = nodes.topic('', title, CLASS='contents')
+ name = nodes.fully_normalize_name(name)
+ if not self.document.has_name(name):
+ topic['name'] = name
+ self.document.note_implicit_target(topic)
+ pending = nodes.pending(parts.Contents)
+ topic += pending
+ self.document.insert(1, topic)
self.document.note_pending(pending)
Modified: Zope/trunk/lib/python/docutils/transforms/references.py
===================================================================
--- Zope/trunk/lib/python/docutils/transforms/references.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/transforms/references.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:09 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:55 $
# Copyright: This module has been placed in the public domain.
"""
@@ -216,7 +216,13 @@
refname = target['refname']
reftarget_id = self.document.nameids.get(refname)
if not reftarget_id:
- self.nonexistent_indirect_target(target)
+ # Check the unknown_reference_resolvers
+ for resolver_function in (self.document.transformer
+ .unknown_reference_resolvers):
+ if resolver_function(target):
+ break
+ else:
+ self.nonexistent_indirect_target(target)
return
reftarget = self.document.ids[reftarget_id]
if isinstance(reftarget, nodes.target) \
@@ -248,7 +254,11 @@
reftarget.referenced = 1
def nonexistent_indirect_target(self, target):
- self.indirect_target_error(target, 'which does not exist')
+ if self.document.nameids.has_key(target['refname']):
+ self.indirect_target_error(target, 'which is a duplicate, and '
+ 'cannot be used as a unique reference')
+ else:
+ self.indirect_target_error(target, 'which does not exist')
def circular_indirect_reference(self, target):
self.indirect_target_error(target, 'forming a circular reference')
@@ -353,7 +363,8 @@
try:
reflist = self.document.refnames[name]
except KeyError, instance:
- if target.referenced:
+ # @@@ First clause correct???
+ if not isinstance(target, nodes.target) or target.referenced:
continue
msg = self.document.reporter.info(
'External hyperlink target "%s" is not referenced.'
Modified: Zope/trunk/lib/python/docutils/transforms/universal.py
===================================================================
--- Zope/trunk/lib/python/docutils/transforms/universal.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/transforms/universal.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Authors: David Goodger, Ueli Schlaepfer
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:09 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:55 $
# Copyright: This module has been placed in the public domain.
"""
@@ -111,6 +111,29 @@
self.document += section
+class FilterMessages(Transform):
+
+ """
+ Remove system messages below verbosity threshold.
+ """
+
+ default_priority = 870
+
+ def apply(self):
+ visitor = SystemMessageFilterVisitor(self.document)
+ self.document.walk(visitor)
+
+
+class SystemMessageFilterVisitor(nodes.SparseNodeVisitor):
+
+ def unknown_visit(self, node):
+ pass
+
+ def visit_system_message(self, node):
+ if node['level'] < self.document.reporter['writer'].report_level:
+ node.parent.remove(node)
+
+
class TestMessages(Transform):
"""
@@ -136,7 +159,9 @@
default_priority = 840
def apply(self):
- visitor = FinalCheckVisitor(self.document)
+ visitor = FinalCheckVisitor(
+ self.document,
+ self.document.transformer.unknown_reference_resolvers)
self.document.walk(visitor)
if self.document.settings.expose_internals:
visitor = InternalAttributeExposer(self.document)
@@ -144,6 +169,11 @@
class FinalCheckVisitor(nodes.SparseNodeVisitor):
+
+ def __init__(self, document, unknown_reference_resolvers):
+ nodes.SparseNodeVisitor.__init__(self, document)
+ self.document = document
+ self.unknown_reference_resolvers = unknown_reference_resolvers
def unknown_visit(self, node):
pass
@@ -154,15 +184,24 @@
refname = node['refname']
id = self.document.nameids.get(refname)
if id is None:
- msg = self.document.reporter.error(
- 'Unknown target name: "%s".' % (node['refname']),
- base_node=node)
- msgid = self.document.set_id(msg)
- prb = nodes.problematic(
- node.rawsource, node.rawsource, refid=msgid)
- prbid = self.document.set_id(prb)
- msg.add_backref(prbid)
- node.parent.replace(node, prb)
+ for resolver_function in self.unknown_reference_resolvers:
+ if resolver_function(node):
+ break
+ else:
+ if self.document.nameids.has_key(refname):
+ msg = self.document.reporter.error(
+ 'Duplicate target name, cannot be used as a unique '
+ 'reference: "%s".' % (node['refname']), base_node=node)
+ else:
+ msg = self.document.reporter.error(
+ 'Unknown target name: "%s".' % (node['refname']),
+ base_node=node)
+ msgid = self.document.set_id(msg)
+ prb = nodes.problematic(
+ node.rawsource, node.rawsource, refid=msgid)
+ prbid = self.document.set_id(prb)
+ msg.add_backref(prbid)
+ node.parent.replace(node, prb)
else:
del node['refname']
node['refid'] = id
Modified: Zope/trunk/lib/python/docutils/urischemes.py
===================================================================
--- Zope/trunk/lib/python/docutils/urischemes.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/urischemes.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,8 @@
"""
`schemes` is a dictionary with lowercase URI addressing schemes as
keys and descriptions as values. It was compiled from the index at
-http://www.w3.org/Addressing/schemes.html (revised 2001-08-20).
+http://www.iana.org/assignments/uri-schemes (revised 2003-11-26)
+and an older list at http://www.w3.org/Addressing/schemes.html.
"""
# Many values are blank and should be filled in with useful descriptions.
@@ -26,10 +27,12 @@
'specialized to justify their own schemes'),
'fax': ('a connection to a terminal that can handle telefaxes '
'(facsimiles); RFC 2806'),
+ 'feed' : 'NetNewsWire feed',
'file': 'Host-specific file names',
'finger': '',
'freenet': '',
'ftp': 'File Transfer Protocol',
+ 'go': 'go; RFC3368',
'gopher': 'The Gopher Protocol',
'gsm-sms': ('Global System for Mobile Communications Short Message '
'Service'),
@@ -40,16 +43,19 @@
'hnews': 'an HTTP-tunneling variant of the NNTP news protocol',
'http': 'Hypertext Transfer Protocol',
'https': 'HTTP over SSL',
+ 'hydra': 'SubEthaEdit URI. See http://www.codingmonkeys.de/subethaedit.',
'iioploc': 'Internet Inter-ORB Protocol Location?',
'ilu': 'Inter-Language Unification',
+ 'im': 'Instant Messaging',
'imap': 'Internet Message Access Protocol',
'ior': 'CORBA interoperable object reference',
'ipp': 'Internet Printing Protocol',
'irc': 'Internet Relay Chat',
+ 'iseek' : 'See www.ambrosiasw.com; a little util for OS X.',
'jar': 'Java archive',
'javascript': ('JavaScript code; evaluates the expression after the '
'colon'),
- 'jdbc': '',
+ 'jdbc': 'JDBC connection URI.',
'ldap': 'Lightweight Directory Access Protocol',
'lifn': '',
'livescript': '',
@@ -62,6 +68,7 @@
'mocha': '',
'modem': ('a connection to a terminal that can handle incoming data '
'calls; RFC 2806'),
+ 'mupdate': 'Mailbox Update (MUPDATE) Protocol',
'news': 'USENET news',
'nfs': 'Network File System protocol',
'nntp': 'USENET news using NNTP access',
@@ -69,8 +76,10 @@
'phone': '',
'pop': 'Post Office Protocol',
'pop3': 'Post Office Protocol v3',
+ 'pres': 'Presence',
'printer': '',
'prospero': 'Prospero Directory Service',
+ 'rdar' : 'URLs found in Darwin source (http://www.opensource.apple.com/darwinsource/).',
'res': '',
'rtsp': 'real time streaming protocol',
'rvp': '',
@@ -80,8 +89,12 @@
'service': 'service location',
'shttp': 'secure hypertext transfer protocol',
'sip': 'Session Initiation Protocol',
- 'smb': '',
+ 'sips': 'secure session intitiaion protocol',
+ 'smb': 'SAMBA filesystems.',
'snews': 'For NNTP postings via SSL',
+ 'soap.beep': '',
+ 'soap.beeps': '',
+ 'ssh': 'Reference to interactive sessions via ssh.',
't120': 'real time data conferencing (audiographics)',
'tcp': '',
'tel': ('a connection to a terminal that handles normal voice '
@@ -90,6 +103,7 @@
'RFC 2806.'),
'telephone': 'telephone',
'telnet': 'Reference to interactive sessions',
+ 'tftp': 'Trivial File Transfer Protocol',
'tip': 'Transaction Internet Protocol',
'tn3270': 'Interactive 3270 emulation sessions',
'tv': '',
@@ -101,5 +115,8 @@
'wais': 'Wide Area Information Servers',
'whodp': '',
'whois++': 'Distributed directory service.',
+ 'x-man-page': 'Opens man page in Terminal.app on OS X (see macosxhints.com)',
+ 'xmlrpc.beep': '',
+ 'xmlrpc.beeps': '',
'z39.50r': 'Z39.50 Retrieval',
'z39.50s': 'Z39.50 Session',}
Modified: Zope/trunk/lib/python/docutils/utils.py
===================================================================
--- Zope/trunk/lib/python/docutils/utils.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/utils.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:04 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:39 $
# Copyright: This module has been placed in the public domain.
"""
@@ -324,7 +324,9 @@
"""
options = {}
for name, value in option_list:
- convertor = options_spec[name] # raises KeyError if unknown
+ convertor = options_spec[name] # raises KeyError if unknown
+ if convertor is None:
+ raise KeyError(name) # or if explicitly disabled
if options.has_key(name):
raise DuplicateOptionError('duplicate option "%s"' % name)
try:
@@ -406,7 +408,7 @@
if len(paragraph) == 1 and isinstance(paragraph[0], nodes.Text):
textnode = paragraph[0]
for pattern, substitution in keyword_substitutions:
- match = pattern.match(textnode.data)
+ match = pattern.search(textnode.data)
if match:
textnode.data = pattern.sub(substitution, textnode.data)
return
Modified: Zope/trunk/lib/python/docutils/writers/__init__.py
===================================================================
--- Zope/trunk/lib/python/docutils/writers/__init__.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/writers/__init__.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Authors: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:09 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:57 $
# Copyright: This module has been placed in the public domain.
"""
@@ -26,25 +26,43 @@
Each writer must support all standard node types listed in
`docutils.nodes.node_class_names`.
- Call `write()` to process a document.
+ The `write()` method is the main entry point.
"""
component_type = 'writer'
config_section = 'writers'
document = None
- """The document to write."""
+ """The document to write (Docutils doctree); set by `write`."""
+ output = None
+ """Final translated form of `document`; set by `translate`."""
+
language = None
- """Language module for the document."""
+ """Language module for the document; set by `write`."""
destination = None
- """`docutils.io` IO object; where to write the document."""
+ """`docutils.io` IO object; where to write the document. Set by `write`."""
def __init__(self):
- """Initialize the Writer instance."""
+ # Currently only used by HTML writer for output fragments:
+ self.parts = {}
+ """Mapping of document part names to fragments of `self.output`.
+ Values are Unicode strings; encoding is up to the client. The 'whole'
+ key should contain the entire document output.
+ """
+
def write(self, document, destination):
+ """
+ Process a document into its final form.
+
+ Translate `document` (a Docutils document tree) into the Writer's
+ native format, and write it out to its `destination` (a
+ `docutils.io.Output` subclass object).
+
+ Normally not overridden or extended in subclasses.
+ """
self.document = document
self.language = languages.get_language(
document.settings.language_code)
@@ -55,9 +73,10 @@
def translate(self):
"""
- Override to do final document tree translation.
+ Do final translation of `self.document` into `self.output`.
+ Called from `write`. Override in subclasses.
- This is usually done with a `docutils.nodes.NodeVisitor` subclass, in
+ Usually done with a `docutils.nodes.NodeVisitor` subclass, in
combination with a call to `docutils.nodes.Node.walk()` or
`docutils.nodes.Node.walkabout()`. The ``NodeVisitor`` subclass must
support all standard elements (listed in
@@ -66,7 +85,11 @@
"""
raise NotImplementedError('subclass must override this method')
+ def assemble_parts(self):
+ """Assemble the `self.parts` dictionary. Extend in subclasses."""
+ self.parts['whole'] = self.output
+
_writer_aliases = {
'html': 'html4css1',
'latex': 'latex2e',
Modified: Zope/trunk/lib/python/docutils/writers/docutils_xml.py
===================================================================
--- Zope/trunk/lib/python/docutils/writers/docutils_xml.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/writers/docutils_xml.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Authors: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:09 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:57 $
# Copyright: This module has been placed in the public domain.
"""
Modified: Zope/trunk/lib/python/docutils/writers/html4css1.py
===================================================================
--- Zope/trunk/lib/python/docutils/writers/html4css1.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/writers/html4css1.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:09 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:57 $
# Copyright: This module has been placed in the public domain.
"""
@@ -22,6 +22,10 @@
import time
import re
from types import ListType
+try:
+ import Image # check for the Python Imaging Library
+except ImportError:
+ Image = None
import docutils
from docutils import frontend, nodes, utils, writers, languages
@@ -55,6 +59,11 @@
'stylesheet, do not embed it.',
['--embed-stylesheet'],
{'action': 'store_true', 'validator': frontend.validate_boolean}),
+ ('Specify the initial header level. Default is 1 for "<h1>". '
+ 'Does not affect document title & subtitle (see --no-doc-title).',
+ ['--initial-header-level'],
+ {'choices': '1 2 3 4 5 6'.split(), 'default': '1',
+ 'metavar': '<level>'}),
('Format for footnote references: one of "superscript" or '
'"brackets". Default is "superscript".',
['--footnote-references'],
@@ -85,9 +94,6 @@
config_section = 'html4css1 writer'
config_section_dependencies = ('writers',)
- output = None
- """Final translated form of `document`."""
-
def __init__(self):
writers.Writer.__init__(self)
self.translator_class = HTMLTranslator
@@ -96,16 +102,19 @@
visitor = self.translator_class(self.document)
self.document.walkabout(visitor)
self.output = visitor.astext()
- self.head_prefix = visitor.head_prefix
- self.stylesheet = visitor.stylesheet
- self.head = visitor.head
- self.body_prefix = visitor.body_prefix
- self.body_pre_docinfo = visitor.body_pre_docinfo
- self.docinfo = visitor.docinfo
- self.body = visitor.body
- self.body_suffix = visitor.body_suffix
+ self.visitor = visitor
+ for attr in ('head_prefix', 'stylesheet', 'head', 'body_prefix',
+ 'body_pre_docinfo', 'docinfo', 'body', 'fragment',
+ 'body_suffix'):
+ setattr(self, attr, getattr(visitor, attr))
+ def assemble_parts(self):
+ writers.Writer.assemble_parts(self)
+ for part in ('title', 'subtitle', 'docinfo', 'body', 'header',
+ 'footer', 'meta', 'stylesheet', 'fragment'):
+ self.parts[part] = ''.join(getattr(self.visitor, part))
+
class HTMLTranslator(nodes.NodeVisitor):
"""
@@ -143,14 +152,14 @@
- Regardless of the above, in definitions, table cells, field bodies,
option descriptions, and list items, mark the first child with
'class="first"' and the last child with 'class="last"'. The stylesheet
- sets the margins (top & bottom respecively) to 0 for these elements.
+ sets the margins (top & bottom respectively) to 0 for these elements.
The ``no_compact_lists`` setting (``--no-compact-lists`` command-line
option) disables list whitespace optimization.
"""
xml_declaration = '<?xml version="1.0" encoding="%s" ?>\n'
- doctype = ('<!DOCTYPE html'
+ doctype = ('<!DOCTYPE html'
' PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'
' "http://www.w3.org/TR/xhtml1/DTD/'
'xhtml1-transitional.dtd">\n')
@@ -171,11 +180,12 @@
self.settings = settings = document.settings
lcode = settings.language_code
self.language = languages.get_language(lcode)
+ self.meta = [self.content_type % settings.output_encoding,
+ self.generator % docutils.__version__]
self.head_prefix = [
self.doctype,
- self.html_head % (lcode, lcode),
- self.content_type % settings.output_encoding,
- self.generator % docutils.__version__]
+ self.html_head % (lcode, lcode)]
+ self.head_prefix.extend(self.meta)
if settings.xml_declaration:
self.head_prefix.insert(0, self.xml_declaration
% settings.output_encoding)
@@ -192,11 +202,17 @@
else:
self.stylesheet = []
self.body_prefix = ['</head>\n<body>\n']
+ # document title, subtitle display
self.body_pre_docinfo = []
+ # author, date, etc.
self.docinfo = []
self.body = []
+ self.fragment = []
self.body_suffix = ['</body>\n</html>\n']
self.section_level = 0
+ self.initial_header_level = int(settings.initial_header_level)
+ # A heterogenous stack used in conjunction with the tree traversal.
+ # Make sure that the pops correspond to the pushes:
self.context = []
self.topic_class = ''
self.colspecs = []
@@ -204,6 +220,11 @@
self.compact_simple = None
self.in_docinfo = None
self.in_sidebar = None
+ self.title = []
+ self.subtitle = []
+ self.header = []
+ self.footer = []
+ self.in_document_title = 0
def get_stylesheet_reference(self, relative_to=None):
settings = self.settings
@@ -267,8 +288,11 @@
parts.append('%s="%s"' % (name.lower(),
self.attval(' '.join(values))))
else:
- parts.append('%s="%s"' % (name.lower(),
- self.attval(unicode(value))))
+ try:
+ uval = unicode(value)
+ except TypeError: # for Python 2.1 compatibility:
+ uval = unicode(str(value))
+ parts.append('%s="%s"' % (name.lower(), self.attval(uval)))
return '<%s%s>%s' % (' '.join(parts), infix, suffix)
def emptytag(self, node, tagname, suffix='\n', **attributes):
@@ -307,7 +331,7 @@
self.body.append(self.starttag(node, 'div',
CLASS=(name or 'admonition')))
if name:
- self.body.append('<p class="admonition-title">'
+ self.body.append('<p class="admonition-title first">'
+ self.language.labels[name] + '</p>\n')
def depart_admonition(self, node=None):
@@ -519,14 +543,14 @@
self.body.append('</tbody>\n</table>\n')
self.in_docinfo = None
start = self.context.pop()
- self.body_pre_docinfo = self.body[:start]
self.docinfo = self.body[start:]
self.body = []
def visit_docinfo_item(self, node, name, meta=1):
if meta:
- self.head.append('<meta name="%s" content="%s" />\n'
- % (name, self.attval(node.astext())))
+ meta_tag = '<meta name="%s" content="%s" />\n' \
+ % (name, self.attval(node.astext()))
+ self.add_meta(meta_tag)
self.body.append(self.starttag(node, 'tr', ''))
self.body.append('<th class="docinfo-name">%s:</th>\n<td>'
% self.language.labels[name])
@@ -546,9 +570,14 @@
self.body.append('\n</pre>\n')
def visit_document(self, node):
- self.body.append(self.starttag(node, 'div', CLASS='document'))
+ # empty or untitled document?
+ if not len(node) or not isinstance(node[0], nodes.title):
+ # for XHTML conformance, modulo IE6 appeasement:
+ self.head.insert(0, '<title></title>\n')
def depart_document(self, node):
+ self.fragment.extend(self.body)
+ self.body.insert(0, self.starttag(node, 'div', CLASS='document'))
self.body.append('</div>\n')
def visit_emphasis(self, node):
@@ -671,6 +700,7 @@
footer = (['<hr class="footer" />\n',
self.starttag(node, 'div', CLASS='footer')]
+ self.body[start:] + ['</div>\n'])
+ self.footer.extend(footer)
self.body_suffix[:0] = footer
del self.body[start:]
@@ -739,9 +769,11 @@
def depart_header(self, node):
start = self.context.pop()
- self.body_prefix.append(self.starttag(node, 'div', CLASS='header'))
- self.body_prefix.extend(self.body[start:])
- self.body_prefix.append('<hr />\n</div>\n')
+ header = [self.starttag(node, 'div', CLASS='header')]
+ header.extend(self.body[start:])
+ header.append('<hr />\n</div>\n')
+ self.body_prefix.extend(header)
+ self.header = header
del self.body[start:]
def visit_hint(self, node):
@@ -756,6 +788,27 @@
del atts['class'] # prevent duplication with node attrs
atts['src'] = atts['uri']
del atts['uri']
+ if atts.has_key('scale'):
+ if Image and not (atts.has_key('width')
+ and atts.has_key('height')):
+ try:
+ im = Image.open(str(atts['src']))
+ except (IOError, # Source image can't be found or opened
+ UnicodeError): # PIL doesn't like Unicode paths.
+ pass
+ else:
+ if not atts.has_key('width'):
+ atts['width'] = im.size[0]
+ if not atts.has_key('height'):
+ atts['height'] = im.size[1]
+ del im
+ if atts.has_key('width'):
+ atts['width'] = int(round(atts['width']
+ * (float(atts['scale']) / 100)))
+ if atts.has_key('height'):
+ atts['height'] = int(round(atts['height']
+ * (float(atts['scale']) / 100)))
+ del atts['scale']
if not atts.has_key('alt'):
atts['alt'] = atts['src']
if isinstance(node.parent, nodes.TextElement):
@@ -837,11 +890,16 @@
self.body.append('\n</pre>\n')
def visit_meta(self, node):
- self.head.append(self.emptytag(node, 'meta', **node.attributes))
+ meta = self.emptytag(node, 'meta', **node.attributes)
+ self.add_meta(meta)
def depart_meta(self, node):
pass
+ def add_meta(self, tag):
+ self.meta.append(tag)
+ self.head.append(tag)
+
def visit_note(self, node):
self.visit_admonition(node, 'note')
@@ -941,6 +999,11 @@
raise nodes.SkipNode
def visit_reference(self, node):
+ if isinstance(node.parent, nodes.TextElement):
+ self.context.append('')
+ else:
+ self.body.append('<p>')
+ self.context.append('</p>\n')
if node.has_key('refuri'):
href = node['refuri']
elif node.has_key('refid'):
@@ -952,6 +1015,7 @@
def depart_reference(self, node):
self.body.append('</a>')
+ self.body.append(self.context.pop())
def visit_revision(self, node):
self.visit_docinfo_item(node, 'revision', meta=None)
@@ -1017,12 +1081,18 @@
self.body.append(self.starttag(node, 'p', '',
CLASS='sidebar-subtitle'))
self.context.append('</p>\n')
- else:
+ elif isinstance(node.parent, nodes.document):
self.body.append(self.starttag(node, 'h2', '', CLASS='subtitle'))
self.context.append('</h2>\n')
+ self.in_document_title = len(self.body)
def depart_subtitle(self, node):
self.body.append(self.context.pop())
+ if self.in_document_title:
+ self.subtitle = self.body[self.in_document_title:-1]
+ self.in_document_title = 0
+ self.body_pre_docinfo.extend(self.body)
+ del self.body[:]
def visit_superscript(self, node):
self.body.append(self.starttag(node, 'sup', ''))
@@ -1135,27 +1205,35 @@
def visit_title(self, node):
"""Only 6 section levels are supported by HTML."""
check_id = 0
+ close_tag = '</p>\n'
if isinstance(node.parent, nodes.topic):
self.body.append(
- self.starttag(node, 'p', '', CLASS='topic-title'))
+ self.starttag(node, 'p', '', CLASS='topic-title first'))
check_id = 1
elif isinstance(node.parent, nodes.sidebar):
self.body.append(
- self.starttag(node, 'p', '', CLASS='sidebar-title'))
+ self.starttag(node, 'p', '', CLASS='sidebar-title first'))
check_id = 1
elif isinstance(node.parent, nodes.admonition):
self.body.append(
- self.starttag(node, 'p', '', CLASS='admonition-title'))
+ self.starttag(node, 'p', '', CLASS='admonition-title first'))
check_id = 1
+ elif isinstance(node.parent, nodes.table):
+ self.body.append(
+ self.starttag(node, 'caption', ''))
+ check_id = 1
+ close_tag = '</caption>\n'
elif self.section_level == 0:
# document title
self.head.append('<title>%s</title>\n'
% self.encode(node.astext()))
self.body.append(self.starttag(node, 'h1', '', CLASS='title'))
self.context.append('</h1>\n')
+ self.in_document_title = len(self.body)
else:
+ h_level = self.section_level + self.initial_header_level - 1
self.body.append(
- self.starttag(node, 'h%s' % self.section_level, ''))
+ self.starttag(node, 'h%s' % h_level, ''))
atts = {}
if node.parent.hasattr('id'):
atts['name'] = node.parent['id']
@@ -1163,17 +1241,22 @@
atts['class'] = 'toc-backref'
atts['href'] = '#' + node['refid']
self.body.append(self.starttag({}, 'a', '', **atts))
- self.context.append('</a></h%s>\n' % (self.section_level))
+ self.context.append('</a></h%s>\n' % (h_level))
if check_id:
if node.parent.hasattr('id'):
self.body.append(
self.starttag({}, 'a', '', name=node.parent['id']))
- self.context.append('</a></p>\n')
+ self.context.append('</a>' + close_tag)
else:
- self.context.append('</p>\n')
+ self.context.append(close_tag)
def depart_title(self, node):
self.body.append(self.context.pop())
+ if self.in_document_title:
+ self.title = self.body[self.in_document_title:-1]
+ self.in_document_title = 0
+ self.body_pre_docinfo.extend(self.body)
+ del self.body[:]
def visit_title_reference(self, node):
self.body.append(self.starttag(node, 'cite', ''))
Modified: Zope/trunk/lib/python/docutils/writers/latex2e.py
===================================================================
--- Zope/trunk/lib/python/docutils/writers/latex2e.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/writers/latex2e.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,8 +1,8 @@
"""
:Author: Engelbert Gruber
:Contact: grubert at users.sourceforge.net
-:Revision: $Revision: 1.3 $
-:Date: $Date: 2003/11/30 15:06:09 $
+:Revision: $Revision: 1.1.2.3.8.1 $
+:Date: $Date: 2004/05/12 19:57:57 $
:Copyright: This module has been placed in the public domain.
LaTeX2e document tree Writer.
@@ -11,7 +11,7 @@
__docformat__ = 'reStructuredText'
# code contributions from several people included, thanks too all.
-# some named: David Abrahams, Julien Letessier, who is missing.
+# some named: David Abrahams, Julien Letessier, Lele Gaifax, and others.
#
# convention deactivate code by two # e.g. ##.
@@ -76,13 +76,43 @@
['--use-latex-toc'],
{'default': 0, 'action': 'store_true',
'validator': frontend.validate_boolean}),
- ('Let LaTeX print author and date, donot show it in docutils document info.',
+ ('Let LaTeX print author and date, do not show it in docutils '
+ 'document info.',
['--use-latex-docinfo'],
{'default': 0, 'action': 'store_true',
'validator': frontend.validate_boolean}),
('Color of any hyperlinks embedded in text '
'(default: "blue", "0" to disable).',
- ['--hyperlink-color'], {'default': 'blue'}),))
+ ['--hyperlink-color'], {'default': 'blue'}),
+ ('Enable compound enumerators for nested enumerated lists '
+ '(e.g. "1.2.a.ii"). Default: disabled.',
+ ['--compound-enumerators'],
+ {'default': None, 'action': 'store_true',
+ 'validator': frontend.validate_boolean}),
+ ('Disable compound enumerators for nested enumerated lists. This is '
+ 'the default.',
+ ['--no-compound-enumerators'],
+ {'action': 'store_false', 'dest': 'compound_enumerators'}),
+ ('Enable section ("." subsection ...) prefixes for compound '
+ 'enumerators. This has no effect without --compound-enumerators. '
+ 'Default: disabled.',
+ ['--section-prefix-for-enumerators'],
+ {'default': None, 'action': 'store_true',
+ 'validator': frontend.validate_boolean}),
+ ('Disable section prefixes for compound enumerators. '
+ 'This is the default.',
+ ['--no-section-prefix-for-enumerators'],
+ {'action': 'store_false', 'dest': 'section_prefix_for_enumerators'}),
+ ('Set the separator between section number and enumerator '
+ 'for compound enumerated lists. Default is "-".',
+ ['--section-enumerator-separator'],
+ {'default': '-', 'metavar': '<char>'}),
+ ('When possibile, use verbatim for literal-blocks.'
+ 'Default is to always use the mbox environment.',
+ ['--use-verbatim-when-possible'],
+ {'default': 0, 'action': 'store_true',
+ 'validator': frontend.validate_boolean}),
+ ))
settings_defaults = {'output_encoding': 'latin-1'}
@@ -245,11 +275,39 @@
'% some commands, that could be overwritten in the style file.\n'
'\\newcommand{\\rubric}[1]'
'{\\subsection*{~\\hfill {\\it #1} \\hfill ~}}\n'
+ '\\newcommand{\\titlereference}[1]{\\textsl{#1}}\n'
'% end of "some commands"\n',
]
}
+class DocumentClass:
+ """Details of a LaTeX document class."""
+ # BUG: LaTeX has no deeper sections (actually paragrah is no
+ # section either).
+ _class_sections = {
+ 'book': ( 'chapter', 'section', 'subsection', 'subsubsection' ),
+ 'report': ( 'chapter', 'section', 'subsection', 'subsubsection' ),
+ 'article': ( 'section', 'subsection', 'subsubsection' ),
+ }
+ _deepest_section = 'subsubsection'
+
+ def __init__(self, document_class):
+ self.document_class = document_class
+
+ def section(self, level):
+ """ Return the section name at the given level for the specific
+ document class.
+
+ Level is 1,2,3..., as level 0 is the title."""
+
+ sections = self._class_sections[self.document_class]
+ if level <= len(sections):
+ return sections[level-1]
+ else:
+ return self._deepest_section
+
+
class LaTeXTranslator(nodes.NodeVisitor):
# When options are given to the documentclass, latex will pass them
# to other packages, as done with babel.
@@ -277,6 +335,16 @@
# list environment for docinfo. else tabularx
use_optionlist_for_docinfo = 0 # NOT YET IN USE
+ # Use compound enumerations (1.A.1.)
+ compound_enumerators = 0
+
+ # If using compound enumerations, include section information.
+ section_prefix_for_enumerators = 0
+
+ # This is the character that separates the section ("." subsection ...)
+ # prefix from the regular list enumerator.
+ section_enumerator_separator = '-'
+
# default link color
hyperlink_color = "blue"
@@ -287,6 +355,11 @@
self.use_latex_docinfo = settings.use_latex_docinfo
self.use_latex_footnotes = settings.use_latex_footnotes
self.hyperlink_color = settings.hyperlink_color
+ self.compound_enumerators = settings.compound_enumerators
+ self.section_prefix_for_enumerators = (
+ settings.section_prefix_for_enumerators)
+ self.section_enumerator_separator = (
+ settings.section_enumerator_separator.replace('_', '\\_'))
if self.hyperlink_color == '0':
self.hyperlink_color = 'black'
self.colorlinks = 'false'
@@ -302,6 +375,9 @@
if self.babel.get_language():
self.d_options += ',%s' % \
self.babel.get_language()
+
+ self.d_class = DocumentClass(settings.documentclass)
+
self.head_prefix = [
self.latex_head % (self.d_options,self.settings.documentclass),
'\\usepackage{babel}\n', # language is in documents settings.
@@ -333,7 +409,7 @@
'\\newlength{\\docinfowidth}\n',
'\\setlength{\\docinfowidth}{0.9\\textwidth}\n'
# linewidth of current environment, so tables are not wider
- # than the sidebar: using locallinewidth seams to defer evaluation
+ # than the sidebar: using locallinewidth seems to defer evaluation
# of linewidth, this is fixing it.
'\\newlength{\\locallinewidth}\n',
# will be set later.
@@ -368,6 +444,7 @@
self.topic_class = ''
# column specification for tables
self.colspecs = []
+ self.table_caption = None
# do we have one or more authors
self.author_stack = None
# Flags to encode
@@ -383,11 +460,24 @@
# enumeration is done by list environment.
self._enum_cnt = 0
+
+ # Stack of section counters so that we don't have to use_latex_toc.
+ # This will grow and shrink as processing occurs.
+ # Initialized for potential first-level sections.
+ self._section_number = [0]
+
+ # The current stack of enumerations so that we can expand
+ # them into a compound enumeration
+ self._enumeration_counters = []
+
# docinfo.
self.docinfo = None
# inside literal block: no quote mangling.
self.literal_block = 0
+ self.literal_block_stack = []
self.literal = 0
+ # true when encoding in math mode
+ self.mathmode = 0
def get_stylesheet_reference(self):
if self.settings.stylesheet_path:
@@ -465,7 +555,7 @@
# then dollar
text = text.replace("$", '{\\$}')
- if not ( self.literal_block or self.literal ):
+ if not ( self.literal_block or self.literal or self.mathmode ):
# the vertical bar: in mathmode |,\vert or \mid
# in textmode \textbar
text = text.replace("|", '{\\textbar}')
@@ -492,7 +582,13 @@
# ! LaTeX Error: There's no line here to end.
text = text.replace("\n", '~\\\\\n')
elif self.mbox_newline:
- text = text.replace("\n", '}\\\\\n\\mbox{')
+ if self.literal_block:
+ closings = "}" * len(self.literal_block_stack)
+ openings = "".join(self.literal_block_stack)
+ else:
+ closings = ""
+ openings = ""
+ text = text.replace("\n", "%s}\\\\\n\\mbox{%s" % (closings,openings))
if self.insert_none_breaking_blanks:
text = text.replace(' ', '~')
# unicode !!!
@@ -528,14 +624,15 @@
def depart_address(self, node):
self.depart_docinfo_item(node)
- def visit_admonition(self, node, name):
+ def visit_admonition(self, node, name=''):
self.body.append('\\begin{center}\\begin{sffamily}\n')
self.body.append('\\fbox{\\parbox{\\admonitionwidth}{\n')
- self.body.append('\\textbf{\\large '+ self.language.labels[name] + '}\n');
+ if name:
+ self.body.append('\\textbf{\\large '+ self.language.labels[name] + '}\n');
self.body.append('\\vspace{2mm}\n')
- def depart_admonition(self):
+ def depart_admonition(self, node=None):
self.body.append('}}\n') # end parbox fbox
self.body.append('\\end{sffamily}\n\\end{center}\n');
@@ -582,6 +679,24 @@
else:
self.body.append( '\\end{itemize}\n' )
+ # Imperfect superscript/subscript handling: mathmode italicizes
+ # all letters by default.
+ def visit_superscript(self, node):
+ self.body.append('$^{')
+ self.mathmode = 1
+
+ def depart_superscript(self, node):
+ self.body.append('}$')
+ self.mathmode = 0
+
+ def visit_subscript(self, node):
+ self.body.append('$_{')
+ self.mathmode = 1
+
+ def depart_subscript(self, node):
+ self.body.append('}$')
+ self.mathmode = 0
+
def visit_caption(self, node):
self.body.append( '\\caption{' )
@@ -601,11 +716,10 @@
self.depart_footnote(node)
def visit_title_reference(self, node):
- # BUG title-references are what?
- pass
+ self.body.append( '\\titlereference{' )
def depart_title_reference(self, node):
- pass
+ self.body.append( '}' )
def visit_citation_reference(self, node):
href = ''
@@ -767,9 +881,11 @@
def visit_emphasis(self, node):
self.body.append('\\emph{')
+ self.literal_block_stack.append('\\emph{')
def depart_emphasis(self, node):
self.body.append('}')
+ self.literal_block_stack.pop()
def visit_entry(self, node):
# cell separation
@@ -781,13 +897,15 @@
# multi{row,column}
if node.has_key('morerows') and node.has_key('morecols'):
- raise NotImplementedError('LaTeX can\'t handle cells that'
+ raise NotImplementedError('LaTeX can\'t handle cells that '
'span multiple rows *and* columns, sorry.')
atts = {}
if node.has_key('morerows'):
+ raise NotImplementedError('multiple rows are not working (yet), sorry.')
count = node['morerows'] + 1
self.body.append('\\multirow{%d}*{' % count)
self.context.append('}')
+ # BUG following rows must have empty cells.
elif node.has_key('morecols'):
# the vertical bar before column is missing if it is the first column.
# the one after always.
@@ -830,13 +948,22 @@
enum_prefix = ""
if node.has_key('prefix'):
enum_prefix = node['prefix']
-
+ if self.compound_enumerators:
+ pref = ""
+ if self.section_prefix_for_enumerators and self.section_level:
+ for i in range(self.section_level):
+ pref += '%d.' % self._section_number[i]
+ pref = pref[:-1] + self.section_enumerator_separator
+ enum_prefix += pref
+ for counter in self._enumeration_counters:
+ enum_prefix += counter + '.'
enum_type = "arabic"
if node.has_key('enumtype'):
enum_type = node['enumtype']
if enum_style.has_key(enum_type):
enum_type = enum_style[enum_type]
counter_name = "listcnt%d" % self._enum_cnt;
+ self._enumeration_counters.append("\\%s{%s}" % (enum_type,counter_name))
self.body.append('\\newcounter{%s}\n' % counter_name)
self.body.append('\\begin{list}{%s\\%s{%s}%s}\n' % \
(enum_prefix,enum_type,counter_name,enum_suffix))
@@ -852,6 +979,7 @@
def depart_enumerated_list(self, node):
self.body.append('\\end{list}\n')
+ self._enumeration_counters.pop()
def visit_error(self, node):
self.visit_admonition(node, 'error')
@@ -964,6 +1092,7 @@
return
self.body.append('}%s' % self.context.pop())
+ # elements generated by the framework e.g. section numbers.
def visit_generated(self, node):
pass
@@ -987,17 +1116,15 @@
self.depart_admonition()
def visit_image(self, node):
- attrs = node.attributes.copy()
+ attrs = node.attributes
pre = [] # in reverse order
post = ['\\includegraphics{%s}' % attrs['uri']]
- def prepost(pre_append, post_append):
- pre.append(pre_append)
- post.append(post_append)
inline = isinstance(node.parent, nodes.TextElement)
if 'scale' in attrs:
# Could also be done with ``scale`` option to
# ``\includegraphics``; doing it this way for consistency.
- prepost('\\scalebox{%f}{' % (attrs['scale'] / 100.0,), '}')
+ pre.append('\\scalebox{%f}{' % (attrs['scale'] / 100.0,))
+ post.append('}')
if 'align' in attrs:
align_prepost = {
# By default latex aligns the top of an image.
@@ -1011,11 +1138,13 @@
(0, 'left'): ('{', '\\hfill}'),
(0, 'right'): ('{\\hfill', '}'),}
try:
- prepost(*align_prepost[inline, attrs['align']])
+ pre.append(align_prepost[inline, attrs['align']][0])
+ post.append(align_prepost[inline, attrs['align']][1])
except KeyError:
- pass # complain here?
+ pass # XXX complain here?
if not inline:
- prepost('\n', '\n')
+ pre.append('\n')
+ post.append('\n')
pre.reverse()
self.body.extend(pre + post)
@@ -1054,6 +1183,8 @@
* whitespace (including linebreaks) is significant
* inline markup is supported.
* serif typeface
+
+ mbox would stop LaTeX from wrapping long lines.
"""
self.body.append('\\begin{flushleft}\n')
self.insert_none_breaking_blanks = 1
@@ -1074,7 +1205,9 @@
self.body.append('\n\\end{flushleft}\n')
def visit_list_item(self, node):
- self.body.append('\\item ')
+ # HACK append "{}" in case the next character is "[", which would break
+ # LaTeX's list environment (no numbering and the "[" is not printed).
+ self.body.append('\\item {} ')
def depart_list_item(self, node):
self.body.append('\n')
@@ -1089,31 +1222,51 @@
def visit_literal_block(self, node):
"""
- .. parsed-literal::
+ Render a literal-block.
+
+ Literal blocks are used for "::"-prefixed literal-indented
+ blocks of text, where the inline markup is not recognized,
+ but are also the product of the parsed-literal directive,
+ where the markup is respected.
+
+ mbox stops LaTeX from wrapping long lines.
"""
- # typically in a typewriter/monospaced typeface.
- # care must be taken with the text, because inline markup is recognized.
+ # In both cases, we want to use a typewriter/monospaced typeface.
+ # For "real" literal-blocks, we can use \verbatim, while for all
+ # the others we must use \mbox.
#
- # possibilities:
- # * verbatim: is no possibility, as inline markup does not work.
- # * obey..: is from julien and never worked for me (grubert).
- self.use_for_literal_block = "mbox"
- self.literal_block = 1
- if (self.use_for_literal_block == "mbox"):
+ # We can distinguish between the two kinds by the number of
+ # siblings the compose this node: if it is composed by a
+ # single element, it's surely is either a real one, otherwise
+ # it's a parsed-literal that does not contain any markup.
+ #
+ if (self.settings.use_verbatim_when_possible and (len(node) == 1)
+ # in case of a parsed-literal containing just a "**bold**" word:
+ and isinstance(node[0], nodes.Text)):
+ self.verbatim = 1
+ self.body.append('\\begin{verbatim}\n')
+ else:
+ self.literal_block = 1
+ self.insert_none_breaking_blanks = 1
+ self.body.append('\\begin{ttfamily}\\begin{flushleft}\n')
self.mbox_newline = 1
- self.insert_none_breaking_blanks = 1
- self.body.append('\\begin{ttfamily}\\begin{flushleft}\n\\mbox{')
- else:
- self.body.append('{\\obeylines\\obeyspaces\\ttfamily\n')
+ if self.mbox_newline:
+ self.body.append('\\mbox{')
+ # * obey..: is from julien and never worked for me (grubert).
+ # self.body.append('{\\obeylines\\obeyspaces\\ttfamily\n')
def depart_literal_block(self, node):
- if (self.use_for_literal_block == "mbox"):
- self.body.append('}\n\\end{flushleft}\\end{ttfamily}\n')
+ if self.verbatim:
+ self.body.append('\n\\end{verbatim}\n')
+ self.verbatim = 0
+ else:
+ if self.mbox_newline:
+ self.body.append('}')
+ self.body.append('\n\\end{flushleft}\\end{ttfamily}\n')
self.insert_none_breaking_blanks = 0
self.mbox_newline = 0
- else:
- self.body.append('}\n')
- self.literal_block = 0
+ # obey end: self.body.append('}\n')
+ self.literal_block = 0
def visit_meta(self, node):
self.body.append('[visit_meta]\n')
@@ -1226,13 +1379,14 @@
# BUG: hash_char "#" is trouble some in LaTeX.
# mbox and other environment do not like the '#'.
hash_char = '\\#'
-
if node.has_key('refuri'):
- href = node['refuri']
+ href = node['refuri'].replace('#',hash_char)
elif node.has_key('refid'):
href = hash_char + node['refid']
elif node.has_key('refname'):
href = hash_char + self.document.nameids[node['refname']]
+ else:
+ raise AssertionError('Unknown reference.')
self.body.append('\\href{%s}{' % href)
def depart_reference(self, node):
@@ -1250,11 +1404,18 @@
def depart_row(self, node):
self.context.pop() # remove cell counter
self.body.append(' \\\\ \\hline\n')
+ # BUG if multirow cells \cline{x-y}
def visit_section(self, node):
self.section_level += 1
+ # Initialize counter for potential subsections:
+ self._section_number.append(0)
+ # Counter for this section's level (initialized by parent section):
+ self._section_number[self.section_level - 1] += 1
def depart_section(self, node):
+ # Remove counter for potential subsections:
+ self._section_number.pop()
self.section_level -= 1
def visit_sidebar(self, node):
@@ -1292,9 +1453,11 @@
def visit_strong(self, node):
self.body.append('\\textbf{')
+ self.literal_block_stack.append('\\textbf{')
def depart_strong(self, node):
self.body.append('}')
+ self.literal_block_stack.pop()
def visit_substitution_definition(self, node):
raise nodes.SkipNode
@@ -1328,13 +1491,20 @@
Return column specification for longtable.
Assumes reST line length being 80 characters.
+ Table width is hairy.
+
+ === ===
+ ABC DEF
+ === ===
+
+ usually gets to narrow, therefore we add 1 (fiddlefactor).
"""
width = 80
total_width = 0.0
# first see if we get too wide.
for node in self.colspecs:
- colwidth = float(node['colwidth']) / width
+ colwidth = float(node['colwidth']+1) / width
total_width += colwidth
# donot make it full linewidth
factor = 0.93
@@ -1343,8 +1513,8 @@
latex_table_spec = ""
for node in self.colspecs:
- colwidth = factor * float(node['colwidth']) / width
- latex_table_spec += "|p{%.2f\\locallinewidth}" % colwidth
+ colwidth = factor * float(node['colwidth']+1) / width
+ latex_table_spec += "|p{%.2f\\locallinewidth}" % (colwidth+0.005)
self.colspecs = []
return latex_table_spec+"|"
@@ -1369,6 +1539,9 @@
def table_preamble(self):
if self.use_longtable:
self.body.append('{%s}\n' % self.get_colspecs())
+ if self.table_caption:
+ self.body.append('\\caption{%s}\\\\\n' % self.table_caption)
+ self.table_caption = None
else:
if self.context[-1] != 'table_sentinel':
self.body.append('{%s}' % ('|X' * self.context.pop() + '|'))
@@ -1476,6 +1649,10 @@
elif isinstance(node.parent, nodes.sidebar):
self.body.append('\\textbf{\\large ')
self.context.append('}\n\\smallskip\n')
+ elif isinstance(node.parent, nodes.table):
+ # caption must be written after column spec
+ self.table_caption = node.astext()
+ raise nodes.SkipNode
elif self.section_level == 0:
# document title
self.title = self.encode(node.astext())
@@ -1487,21 +1664,15 @@
self.body.append('%' + '_' * 75)
self.body.append('\n\n')
self.bookmark(node)
- # section_level 0 is title and handled above.
- # BUG: latex has no deeper sections (actually paragrah is no section either).
+
if self.use_latex_toc:
section_star = ""
else:
section_star = "*"
- if (self.section_level<=3): # 1,2,3
- self.body.append('\\%ssection%s{' % ('sub'*(self.section_level-1),section_star))
- elif (self.section_level==4):
- #self.body.append('\\paragraph*{')
- self.body.append('\\subsubsection%s{' % (section_star))
- else:
- #self.body.append('\\subparagraph*{')
- self.body.append('\\subsubsection%s{' % (section_star))
- # BUG: self.body.append( '\\label{%s}\n' % name)
+
+ section_name = self.d_class.section(self.section_level)
+ self.body.append('\\%s%s{' % (section_name, section_star))
+
self.context.append('}\n')
def depart_title(self, node):
Modified: Zope/trunk/lib/python/docutils/writers/pep_html.py
===================================================================
--- Zope/trunk/lib/python/docutils/writers/pep_html.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/writers/pep_html.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Author: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:09 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:57 $
# Copyright: This module has been placed in the public domain.
"""
@@ -88,15 +88,6 @@
class HTMLTranslator(html4css1.HTMLTranslator):
- def get_stylesheet_reference(self, relative_to=None):
- settings = self.settings
- if relative_to == None:
- relative_to = settings._destination
- if settings.stylesheet_path:
- return utils.relative_path(relative_to, settings.stylesheet_path)
- else:
- return settings.stylesheet
-
def depart_field_list(self, node):
html4css1.HTMLTranslator.depart_field_list(self, node)
if node.get('class') == 'rfc2822':
Modified: Zope/trunk/lib/python/docutils/writers/pseudoxml.py
===================================================================
--- Zope/trunk/lib/python/docutils/writers/pseudoxml.py 2004-05-13 14:53:16 UTC (rev 24624)
+++ Zope/trunk/lib/python/docutils/writers/pseudoxml.py 2004-05-13 15:25:53 UTC (rev 24625)
@@ -1,7 +1,7 @@
# Authors: David Goodger
# Contact: goodger at users.sourceforge.net
-# Revision: $Revision: 1.5 $
-# Date: $Date: 2003/11/30 15:06:09 $
+# Revision: $Revision: 1.2.10.3.8.1 $
+# Date: $Date: 2004/05/12 19:57:57 $
# Copyright: This module has been placed in the public domain.
"""
More information about the Zope-Checkins
mailing list