From a98c9eaac3af332308c1d2070a73890d77f575ff Mon Sep 17 00:00:00 2001 From: Erik Stein Date: Mon, 4 Jun 2018 16:38:28 +0200 Subject: [PATCH] Initial import from svn tag 0.14. --- .gitignore | 1 + HISTORY.txt | 3243 ++++++++++++++++++++++++++++ README.txt | 394 ++++ RELEASE-NOTES.txt | 665 ++++++ docutils/__init__.py | 262 +++ docutils/transforms/__init__.py | 172 ++ docutils/transforms/components.py | 52 + docutils/transforms/frontmatter.py | 532 +++++ docutils/transforms/misc.py | 144 ++ docutils/transforms/parts.py | 180 ++ docutils/transforms/peps.py | 305 +++ docutils/transforms/references.py | 913 ++++++++ docutils/transforms/universal.py | 311 +++ docutils/transforms/writer_aux.py | 88 + 14 files changed, 7262 insertions(+) create mode 100644 .gitignore create mode 100644 HISTORY.txt create mode 100644 README.txt create mode 100644 RELEASE-NOTES.txt create mode 100644 docutils/__init__.py create mode 100644 docutils/transforms/__init__.py create mode 100644 docutils/transforms/components.py create mode 100644 docutils/transforms/frontmatter.py create mode 100644 docutils/transforms/misc.py create mode 100644 docutils/transforms/parts.py create mode 100644 docutils/transforms/peps.py create mode 100644 docutils/transforms/references.py create mode 100644 docutils/transforms/universal.py create mode 100644 docutils/transforms/writer_aux.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..93f5714 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/.svn/ diff --git a/HISTORY.txt b/HISTORY.txt new file mode 100644 index 0000000..8446d64 --- /dev/null +++ b/HISTORY.txt @@ -0,0 +1,3243 @@ +.. -*- coding: utf-8 -*- + +================== + Docutils History +================== + +:Author: David Goodger; open to all Docutils developers +:Contact: docutils-develop@lists.sourceforge.net +:Date: $Date: 2017-08-03 11:01:16 +0200 (Do, 03 Aug 2017) $ +:Revision: $Revision: 8147 $ +:Web site: http://docutils.sourceforge.net/ +:Copyright: This document has been placed in the public domain. + +.. contents:: + + +Release 0.14 (2017-08-03) +========================= + +As rc2. + +* docs/ref/docutils.dtd: + + - Enable validation of Docutils XML documents against the DTD: + + Use attribute type NMTOKEN instead of REFID for the `refid` attribute + and NMTOKENS for `backrefs`: REFID refers to an ID type instance, + however, the `ids` attribute cannot use the ID type because `XML only + allows one ID per Element Type`__ and doesn't support a multiple-ID + "IDS" attribute type. + + __ https://www.w3.org/TR/REC-xml/#sec-attribute-types + +* docs/ref/rst/restructuredtext.txt: + + - Added documentation for escaped whitespace in URI contexts. + - Clarify use of Unicode character categories. + +* docutils/parsers/rst/states.py: + + - Added functionality: escaped whitespace in URI contexts. + - Consistent handling of all whitespace characters in inline markup + recognition. Fixes [ 307 ] and [ 3402314 ] (now [ 173 ]). + +* docutils/parsers/rst/directives/images.py: + + - Added support for escaped whitespace in URI contexts. + +* docutils/parsers/rst/directives/tables.py: + + - Rework patch [ 120 ] (revert change to ``Table.get_column_widths()`` + that led to problems in an application with a custom table directive). + +* docutils/transforms/frontmatter.py + + - Fix [ 320 ] Russian docinfo fields not recognized. + +* docutils/transforms/references.py + + - Don't add a second ID to problematic references. + +* docutils/transforms/universal.py + + Fix SmartQuotes: warn only once if language is unsupported, + keep "rawsource" when "educating" quotes. + +* docutils/utils/__init__.py: + + - Added ``split_escaped_whitespace`` function, support for escaped + whitespace in URI contexts. + +* docutils/utils/error_reporting.py + + - Fix [ 321 ] Import block might cause name error. + +* docutils/utils/smartquotes.py: + + - Update quote definitions for languages et, fi, fr, ro, sv, tr, uk. + - New quote definitions for hr, hsb, hu, lv, sh, sl, sr. + - Fix [ 313 ] Differentiate apostrophe from closing single quote + (if possible). + - Fix [ 317 ] Extra space inserted with French smartquotes. + - Add command line interface for stand-alone use (requires 2.7). + +* docutils/writers/_html_base.py + + - Provide default title in metadata (required by HTML5). + - Fix [ 312 ] HTML writer generates invalid HTML if the table has two tags. + - Fix [ 319 ] The MathJax CDN shut down on April 30, 2017. For security + reasons, we don't use a third party public installation as default but + warn if math-output_ is set to MathJax without specifying a URL. + +* docutils/writers/html4css1/__init__.py + + - Apply [ 125 ] HTML writer: respect automatic table column sizing. + +* docutils/writers/latex2e/__init__.py + + - Handle class arguments for block-level elements by wrapping them + in a "DUclass" environment. This replaces the special handling for + "epigraph" and "topic" elements. + +* docutils/writers/manpage.py + + - Apply [ 141 ] Handling inline in manpage writer. + +* docutils/writers/odf_odt/__init__.py: + + - Command setting ``language`` now sets the default language + of the generated ODF document. + - The use of image directive options :width: (%), :scale:, etc now + set the width/height/size of images in the generated ODF + documents. + - The heading/title of admonitions now reflects the language + specified by the ``language`` setting. + - Fixed [ 306 ] only first of multiple "image" directives with the same URL + shown in output. + - Fixed [ 282 ] python3: AttributeError. + +* tools/rst2html4.py: New front-end. + +* tools/dev/generate_punctuation_chars.py: New skript + to test and update utils.punctuation_chars. + + +Release 0.13.1 (2016-12-09) +=========================== + +* docutils/languages/fa.py + docutils/parsers/rst/languages/fa.py + docutils/languages/la.py + docutils/parsers/rst/languages/la.py: + + - Apply [ 133 ] Persian mappings by Shahin Azad. + - Apply [ 135 ] Language modules for Latvian by Alexander Smishlajev + +* docutils/nodes.py + + - Fix [ 253 ] Attribute key without value not allowed in XML. + +* docutils/parsers/ + + - Apply [ 103 ] Recognize inline markups without word boundaries. + - Enable escaping in embedded URIs and aliases (fixes [ 284 ]). + +* docutils/parsers/rst/__init__.py + + - Fix [ 233 ] Change the base URL for the :rfc: role. + +* docutils/parsers/rst/directives/tables.py + + - Apply [ 120 ] tables accept option widths: list of relative widths, 'auto' + or 'grid'. + + - Implement feature request [ 48 ] + Add :align: option to the table directives. + Thanks to Takeshi KOMIYA for the patch. + +* docutils/parsers/rst/roles.py + + - Fix [ 295 ] Class argument for custom role inheriting from math. + +* docutils/parsers/rst/tableparser.py + + - Really fix [ 159 ] Spurious table column alignment errors. + +* docutils/transforms/frontmatter.py + + - Add name of generic bibliographic fields as a "classes" attribute value + (after conversion to a valid identifier form). + +* docutils/utils/error_reporting.py + + - Fix [ 130 ] support streams expectiong byte-strings in ErrorOutput. + +* docutils/utils/math/math2html.py + + - Add ``\colon`` macro, fix spacing around colons. Fixes [ 246 ]. + - New upstream version (additional macros, piecewise integrals and sums). + +* docutils/writers/_html_base.py + + - New auxiliary module for definitions common to all HTML writers. + +* docutils/writers/html5_polyglot/ + + - New HTML writer generating clean, polyglot_ markup conforming to + `HTML 5`_. + + The CSS stylesheets ``minimal.css`` and ``plain.css`` contain required + and recommended layout rules. + +* docutils/writers/html4css1/__init__.py + + - Add "docutils" to class values for "container" object to address [ 267 ]. + - Apply patch [ 119 ] by Anatoly Techtonik: use absolute paths for + ``default_stylesheet_path`` and ``default_template_path``. + - Fix [ 266 ] creating labels/class values in description list items. + - Do not use and tags inside
 (parsed-literal blocks).
+  - Fix footnotes with content that does not start with a paragraph.
+  - Use https in default MathJax URL (report Alan G Isaac).
+  - Outsourcing of common code to _html_base.py.
+
+* docutils/writers/latex2e/__init__.py
+
+  - Fix [ 262 ] Use ``\linewidth`` instead of ``\textwidth`` for figures,
+    admonitions and docinfo.
+
+  - Use absolute path for ``default_template_path``.
+
+  - Removed deprecated options ``--use-latex-footnotes`` and
+    ``--figure-footnotes``.
+
+  - Cleaner LaTeX code for enumerations and literal blocks.
+
+  - Use "hyperref" package together with "bookmark" (improved hyperlinking
+    by the same author).
+
+  - Fix [ 286 ] Empty column title cause invalid latex file.
+
+  - Fix [ 224 ] Fix rowspan support for tables.
+
+  - Let LaTeX determine the column widths in tables with "colwidths-auto".
+    Not suited for multi-paragraph cells!
+
+* docutils/writers/odf_odt/__init__.py
+
+  - remove decode.encode of filename stored in zip.
+
+* docutils/writers/xetex/__init__.py
+
+  - LuaLaTex compatibility: do not load "xunicode".
+
+* tools/
+
+  - New front-end ``rst2html5.py``.
+
+* tox.ini
+
+  - Test py26, py27, py33 and py34.
+
+    To use, install the ``tox`` package via pip or easy_install and use
+    tox from the project root directory.
+
+.. _polyglot: http://www.w3.org/TR/html-polyglot/
+.. _HTML 5: http://www.w3.org/TR/html5/
+.. _XHTML 1.0: http://www.w3.org/TR/xhtml1/
+
+
+Release 0.12 (2014-07-06)
+=========================
+
+* docs/ref/rst/directives.txt
+
+  - Update "math" and "csv-table" descriptions.
+
+* docutils/parsers/rst/directives/images.py
+
+  - Fix [ 258 ] figwidth="image" generates unitless width value.
+
+* docutils/parsers/rst/states.py
+
+  - Improve error report when a non-ASCII character is specified as
+    delimiter, quote or escape character under Python 2.
+    Fixes [ 249 ] and [ 250 ].
+
+* docutils/writers/html4css1/__init__.py
+
+  - Don't add newline after inline math.
+    Thanks to Yury G. Kudryashov for the patch.
+
+* docutils/writers/latex2e/__init__.py
+
+  - Fix [ 239 ] Latex writer glues paragraphs with figure floats.
+  - Apply [ 116 ] by Kirill Smelkov. Don't hardcode \large for subtitle.
+
+* docutils/writers/odf_odt/__init__.py
+
+  - Apply patch by Jakub Wilk to fix bug [ 100 ].
+
+* test/test_error_reporting.py
+
+  - Fix [ 223 ] by removing redundant tests we do not have control over.
+
+* test/test_nodes.py
+
+  - Apply [ 115 ] respect fixed 2to3 string literal conversion behavior.
+
+Release 0.11 (2013-07-22)
+=========================
+
+* General
+
+  - Apply [ 2714873 ] Fix for the overwritting of document attributes.
+  - Support embedded aliases within hyperlink references.
+  - Fix [ 228 ] try local import of docutils components (reader, writer, parser,
+    language module) before global search.
+
+* docutils/nodes.py
+
+  - Fix [ 3601607 ] node.__repr__() must return `str` instance.
+
+* docutils/parsers/rst/directives/__init__.py
+
+  - Fix [ 3606028 ] ``assert`` is skipped with ``python -O``.
+
+* docutils/parsers/rst/directives/images.py
+
+  - Apply [ 3599485 ] node source/line information for sphinx translation.
+
+* docutils/parsers/rst/directives/tables.py
+
+  - Fix [ 210 ] Python 3.3 checks CVS syntax only if "strict" is True.
+
+* docutils/parsers/rst/states.py
+
+  - Fix [ 157 ] Line block parsing doesn't like system message.
+  - Always import our local copy of roman.py (report Larry Hastings).
+
+* docutils/transforms/references.py
+
+  - Fix [ 3607029 ] traceback with embedded alias pointing to missing target.
+
+* docutils/utils/__init__.py
+
+  - Fix [ 3596884 ] exception importing ``docutils.io``.
+
+* docutils/writers/html4css1/__init__.py
+
+  - Fix [ 3600051 ] for tables in a list, table cells are not compacted.
+  - New setting `stylesheet_dirs`: Comma-separated list of directories
+    where stylesheets are found. Used by `stylesheet_path` when expanding
+    relative path arguments.
+  - New default for math-output_: ``HTML math.css``.
+  - Avoid repeated class declarations in html4css1 writer
+    (modified version of patch [ 104 ]).
+
+.. _math-output: docs/user/config.html#math-output
+
+* docutils/writers/latex2e/__init__.py
+
+  - Drop the simple algorithm replacing straight double quotes with
+    English typographic ones.
+    Activate the SmartQuotes_ transform if you want this feature.
+  - Fix literal use of babel shorthands (straight quote, tilde, ...).
+  - Fix [ 3603246 ] Bug in option "--graphicx-option=auto".
+  - New setting `stylesheet_dirs`.
+
+.. _SmartQuotes: docs/user/config.html#smart-quotes
+
+* docutils/writers/manpage.py
+
+  - Fix [3607063] handle lines starting with a period.
+  - Fix option separating comma was bold (thanks to Bill Morris).
+
+Release 0.10 (2012-12-16)
+=========================
+
+* General
+
+  - Dropped support for Python 2.3.
+  - ``docutils/math``, ``docutils/error_reporting.py``, and
+    ``docutils/urischemes.py`` moved to the utils package.
+  - Fix [3541369] Relative __import__ also with Python 3.3.
+  - Fix [3559988] and [3560841] __import__ local writer, reader, languages
+    and parsers for Python 2.7 up.
+  - Fix import of PIL.Image.
+  - Change default of "syntax highlight" option to "long",
+    basic syntax highlight styles for LaTeX and HTML.
+
+* docutils/io.py
+
+  - FileInput/FileOutput: no system-exit on IOError.  The `handle_io_errors`
+    option is ignored and will be removed in a future release.
+  - Fix Py3k error writing to stdout with encoding differing from default.
+  - Fix opening binary files under Py3k (thanks to Dominic Fitzpatrick).
+
+* docutils/parsers/rst/directives/misc.py
+
+  - Fix [ 3546533 ] Unicode error with `date` directive.
+
+* docutils/transforms/universal.py
+
+  - SmartQuotes transform for typographic quotes and dashes.
+
+* docutils/utils/__init__.py
+
+  - normalize_language_tag() now returns `BCP 47`_ conformant tags
+    with subtags separated by ``-``.
+
+* docutils/writers/html4css1/__init__.py
+
+  - Use ```` tag for inline "code",
+    do not drop nested inline nodes (syntax highlight tokens).
+  - Customizable MathJax URL (based on patch by Dmitry Shachnev).
+  - No line break after opening inline math tag.
+
+* docutils/writers/manpage.py
+
+  - Apply [ 3527401 ] addmonition's don't preserve indentation
+  - Apply [ 3527397 ] Add indentation to literal blocks in manpage writer.
+
+* docutils/writers/xetex/__init__.py
+
+  - Apply [ 3555160 ] ensure order of "otherlanguages".
+  - Fix section numbering by LaTeX.
+
+* docutils/writers/s5_html/__init__.py
+
+  - Fix [ 3556388 ] Mathjax does not work with rst2s5.
+
+* docutils/writers/s5_html/docutils_xml.py
+
+  - Fix [ 3552403 ] Prevent broken PyXML replacing stdlibs xml module.
+  - Fix/improve output with ``--indent`` option.
+
+* setup.py
+
+  - Tag ``math.css`` stylesheet as data file (patch by Dmitry Shachnev).
+
+* tools/test/test_buildhtml.py
+
+  - Fix [ 3521167 ] allow running in any directory.
+  - Fix [ 3521168 ] allow running with Python 3.
+
+
+Release 0.9.1 (2012-06-17)
+==========================
+
+* setup.py
+
+  - Fix [ 3527842 ]. Under Python 3, converted tests and tools were
+    installed in the PYTHONPATH. Converted tests are now
+    stored in ``test3/``, tools no longer need conversion.
+
+    If you installed one of Docutils versions 0.7 ... 0.9 with
+    ``setup.py install`` under Python 3, remove the spurious
+    ``test/`` and ``tools/`` directories in the site library root.
+
+* test/
+
+  - Make tests independent from the location of the ``test/`` directory.
+  - Use converted sources (from the ``build/`` directory) for tests under
+    Python 3.
+
+* tools/
+
+  - Make tools compatible with both, Python 2 and 3 without 2to3-conversion.
+
+* docutils/io.py
+
+  - Fix writing binary data to sys.stdout under Python 3 (allows
+    ``rst2odt.py`` to be used with output redirection).
+
+* docutils/parsers/rst/directives/misc.py
+
+  - Fix [ 3525847 ]. Catch and report UnicodeEncodeError with
+    ``locale == C`` and 8-bit char in path argument of `include` directive.
+
+* test/alltests.py
+
+  - class `Tee`: catch UnicodeError when writing to "ascii" stream or
+    file under Python 3.
+
+Release 0.9 (2012-05-02)
+========================
+
+* General:
+
+  - New reStructuredText "code" role and directive and "code" option
+    of the "include" directive with syntax highlighting by Pygments_.
+  - Fix parse_option_marker for option arguments containing ``=``.
+  - Fix [ 2993756 ]: import Python Imaging Library's Image module
+    via ``import PIL`` as starting with PIL 1.2,
+    "PIL lives in the PIL namespace only" (announcement__).
+
+.. _Pygments: http://pygments.org/
+__ http://mail.python.org/pipermail/image-sig/2011-January/006650.html
+
+* setup.py
+
+  - Fix [ 2971827 ] and [ 3442827 ]
+    extras/roman.py moved to docutils/utils/roman.py
+
+* docutils/frontend.py
+
+  - Fix [ 3481980 ] Use os.getcwdu() in make_paths_absolute().
+
+* docutils/io.py
+
+  - Fix [ 3395948 ] (Work around encoding problems in Py3k).
+  - `mode` argument for FileOutput avoids code replication in
+    BinaryFileOutput.
+  - New exceptions InputError and OutputError for IO errors in
+    FileInput/FileOutput.
+
+* docutils/core.py:
+
+  - No "hard" system exit on file IO errors: catch and report them in
+    `Publisher.reportException` instead. Allows handling by a calling
+    application if the configuration setting `traceback` is True.
+
+* docutils/utils.py -> docutils/utils/__init__.py
+
+  - docutils.utils is now a package (providing a place for sub-modules)
+
+  .. note:: docutils/math, docutils/error_reporting.py, and
+     docutils/urischemes.py will move to the utils package in the next
+     release, too. See RELEASE-NOTES__
+
+     __ RELEASE-NOTES.html
+
+  - DependencyList uses io.FileOutput and 'utf8' encoding to prevent
+    errors recording non-ASCII filenames (fixes [ 3434355 ]).
+
+  - Fix relative_path() with source=None and `unicode` target.
+
+* docutils/parsers/rst/states.py
+
+  - Fix [ 3402314 ] allow non-ASCII whitespace, punctuation
+    characters and "international" quotes around inline markup.
+  - Use `field_marker` pattern to look for start of a
+    directive option block (fixes [ 3484857 ]).
+
+* docutils/parsers/rst/tableparser.py
+
+  - Fix [ 2926161 ] for simple tables.
+    (Combining chars in grid tables still contribute to cell width.)
+
+* docutils/writers/latex2e/__init__.py
+
+  - Support the `abbreviation` and `acronym` standard roles.
+  - Record only files required to generate the LaTeX source as dependencies.
+  - Fix handling of missing stylesheets.
+  - Use ``\setcounter{secnumdepth}{0}`` instead of ``*``-versions
+    when suppressing LaTeX section numbering.
+  - Use ``\DUtitle`` for unsupported section levels
+  - Apply [ 3512791 ] do not compare string literals with "is"
+
+* docutils/writers/xetex/__init__.py
+
+  - Avoid code duplication with latex2e writer (solves [ 3512728 ]).
+
+* docutils/writers/html4css1/__init__.py
+
+  - Change default for `math-output` setting to MathJax.
+  - Fix handling of missing stylesheets.
+
+* docutils/writers/docutils_xml.py
+
+  - Use the visitor pattern with default_visit()/default_depart() methods
+    instead of minidom to facilitate special handling of selected nodes.
+  - Support raw XML (inserted as-is inside a  node).
+
+* docutils/writers/manpage.py
+
+  - Do not emit comment line with trailing blank. Problematic for VCS.
+
+Release 0.8.1 (2011-08-30)
+==========================
+
+* General:
+
+  - Fix [ 3364658 ] (Change last file with Apache license to BSD-2-Clause)
+    and [ 3395920 ] (correct copyright info for rst.el).
+
+* test/
+
+  -  Apply [ 3303733 ] and [ 3365041 ] to fix tests under Py3k.
+
+* docutils/writers/latex2e/__init__.py
+
+  - Clean up Babel language setting. Restores Sphinx compatibility.
+
+Release 0.8 (2011-07-07)
+========================
+
+* General:
+
+  - Handle language codes according to `BCP 47`_.
+  - If the specified language is not supported by Docutils,
+    warn and fall back to English.
+  - Math support: reStructuredText "math" role and directive,
+    ``math`` and ``math_block`` doctree elements.
+  - Decode command line arguments with the locale's preferred encoding
+    (to allow, e.g., ``--title=Dornröschen``).
+  - Orphaned "python" reader and "newlatex2e" writer moved to the sandbox.
+  - New sub-module `error_reporting`: handle encoding/decoding errors
+    when reporting exceptions.
+  - Some additions to the Docutils core are released under the 2-Clause BSD
+    license, see COPYING_ for details.
+
+  .. _BCP 47: http://www.rfc-editor.org/rfc/bcp/bcp47.txt
+  .. _COPYING: COPYING.html
+
+* reStructuredText:
+
+  - Most directives now support a "name" option that attaches a
+    reference name.
+
+  - Directive content may start on the first line also when the directive
+    type accepts options.
+
+* docs/dev/policies.txt:
+
+  - Recommend the 2-Clause BSD license
+    (http://www.spdx.org/licenses/BSD-2-Clause)
+    for code that is kept under the author's copyright.
+
+* tools/buildhtml.py:
+
+  - Fix ``--local`` switch.
+
+* Fix [ 3018371 ] Added Lithuanian mappings by Dalius Dobravolskas.
+
+* docutils/writers/html4css1/__init__.py
+
+  - Set "lang" argument for objects with class argument
+    "language-".
+  - New setting "math-output" with support for HTML, MathML, and LaTeX.
+
+* docutils/writers/latex2e/__init__.py
+
+  - Fix [ 3043986 ] AttributeError using :local: with table of content.
+  - Place title data in the document preamble.
+  - Load `babel` package only if required.
+  - Update list of supported languages.
+  - New config setting "hyperref-options".
+    No hard-coded "unicode" hyperref option (clash with xetex).
+  - Set language for custom roles, paragraphs, block-quotes, and
+    line-quotes with class argument "language-".
+  - Fix [ 3095603 ] wrong quotes output for russian and other languages.
+  - Convert image URI to a local file path.
+  - Apply [ 3148141 ] fix multicolumn support when a colspanning cell
+    has more than one paragraph (Wolfgang Scherer).
+  - \leavevmode before longtable only when needed (prevents spurious vspace)
+  - do not advance table counter for tables without caption
+
+* docutils/writers/xetex/__init__.py
+
+  - New writer generating LaTeX code for compiling with ``xelatex``.
+
+    A separate writer (inheriting from latex2e) instead of a ``--xetex``
+    option allows separate config options for XeTeX vs. LaTeX2e.
+
+* docutils/writers/manpage.py
+
+  - Fix: BUG#3219183 - vertical space in definition lists containing markup.
+  - Fix: vertical space cleaning for option group ``.``.
+
+* tools/editors/emacs/rst.el:
+
+  - Fix [ 3001100 ] does not handle spaces in filenames
+    (thanks to Jakub Wilk)
+
+* docutils/utils.py:
+
+  - strip whitespace from stylesheet arguments
+  - exclude combining chars from column_width()
+    (partial fix for [ 2926161 ])
+
+* docutils/parsers/rst/directives/misc.py:
+
+  - Fix [ 1830389 ] Replace not breaking on getting system_messages from
+    nested_parse
+
+* docutils/io.py:
+
+  - Do not close() sys.stdin, sys.stdout, or sys.stderr. Prevents
+    ``Exception ValueError: 'I/O operation on closed file.'`` with Python 3.
+
+Release 0.7 (2010-07-07)
+========================
+
+* General:
+
+  - Fix [ 2881769 ] setup configuration.
+  - Fix [ 2788716 ] reporting problems in included files.
+
+* docutils/io.py
+
+  - FileInput opens files as text files with universal newline support
+    (mode "rU", configurable with the new optional argument "mode").
+
+* docutils/nodes.py
+
+  - Fix [ 2975987 ] repr(Text) failed with long string (Jeffrey C. Jacobs).
+
+* docutils/utils.py
+
+  - Fix [ 2923723 ] let decode_path() tolerate path == None
+
+* docutils/writers/html4css1/__init__.py
+
+  - Support SVG and SWF images (thanks to Stefan Rank).
+  - Generate valid XHTML for centered images with targets.
+    Use CSS classes instead of "align" tags for image alignment.
+
+* docutils/writers/latex2e/__init__.py
+
+  - Use `transforms.writer_aux.Admonitions` to "normalize" special
+    admonitions.
+  - Use the ``\url`` command for URLs (breaks long URLs instead of
+    writing into the margin).
+  - Preserve runs of spaces in `inline literals`__.
+  - Deprecate ``figure_footnotes`` setting.
+  - Rename ``use_latex_footnotes`` setting to `docutils_footnotes`__.
+  - New ``latex_preamble`` setting.
+  - Use PDF standard fonts (Times/Helvetica/Courier) as default.
+  - Fix hyperlink targets (labels) for images, figures, and tables.
+  - Apply [ 2961988 ] Load babel after inputenc and fontenc.
+  - Apply [ 2961991 ] Call hyperref with unicode option.
+  - Drop the special `output_encoding`__ default ("latin-1").
+    The Docutils wide default (usually "UTF-8") is used instead.
+  - Render inline markup in document title and subtitle.
+  - Fix numbering depth with LaTeX section numbering.
+  - Update Unicode -> LaTeX translations.
+  - Fix bug with topic directive (thanks to Alan G Isaac for reporting).
+
+__ docs/ref/restructuredtext.html#inline-literals
+__ docs/user/config.html#docutils-footnotes
+__ docs/user/config.html#output_encoding
+
+* docutils/writers/manpage.py
+
+  - Fix: supported attribute (thanks to peter2108).
+  - Remove trailing blanks in code (keep in sync with mercurial version).
+  - Titles level 1, that is ``.SH``, always uppercase.
+  - Apply patch from mg: literal text should be bold in man-pages.
+
+* docutils/nodes.py
+
+  - Fix: encoding ``'ascii'`` must be lowercase to prevent problems for
+    turkish locale.
+
+* setup.py:
+
+  - Python 3 support: copy test/ and tools/ to the build-dir
+    and convert Python sources with 2to3.
+
+
+Release 0.6 (2009-10-11)
+========================
+
+* General:
+
+  - Docutils is now compatible with Python versions from 2.3 up to 2.6
+    and convertible to 3.1 code.
+
+    + Node.__nonzero__ returns True instead of 1.
+    + use os.walk instead os.path.walk.
+    + minimize "types" module where possible.
+    + Backwards-compatible changes to remove python2.6 -3 deprecation warnings
+    + Text nodes now subclass unicode rather than UserString
+      (which is gone in python 3.0).
+    + 3.0 compatibility module docutils._compat
+
+    + Drop 2.2 compatibility workarounds.
+    + Drop extras/optparse.py and extras/textwrap.py
+      (stdlib modules since 2.3).
+
+  - OpenOffice export: ODT writer moved from sandbox to Doctutils core.
+  - Unix man page export: manpage writer moved from sandbox to Doctutils
+    core.
+
+  - Apply [ 1719345 ] Galician translation
+  - Apply [ 1905741 ] Polish translation
+  - Apply [ 1878977 ] make_id(): deaccent characters.
+  - Apply [ 2029251 ] return nonzero when tests fail.
+  - Fix [ 1692788 ] allow UTF-8 in style sheets.
+  - Fix [ 2781629 ] support non-ASCII chars in file names.
+  - Apply [ 2845002 ] let ``--no-raw`` disable raw *roles* too.
+  - Fix [ 2831643 ] by renaming DirectiveError.message to DirectiveError.msg
+  - Fix [ 2821266 ] --strict option works now like --halt=info.
+  - Fix [ 2788716 ] DirectiveError now correctly reports source and line.
+  - Fix [ 1627229 ] hyperlink references in substitutions.
+
+  - The "newlatex" writer is orphaned.
+
+* reStructuredText:
+
+  - Documented Unicode characters allowed as inline markup openers,
+    closers, and delimiters.
+  - Allow units for all length specifications.
+  - Allow percent sign in "scale" argument of "figure" and "image" directives.
+  - Bugfix: The "figalign" argument of a figure now works as intended
+    (aligning the figure, not its contents).
+  - Align images with class "align-[right|center|left]"
+    (allows setting the alignment of an image in a figure).
+
+* docutils/nodes.py:
+
+  - Added ``Element.__contains__`` method, for the in-operator.
+
+* docutils/parsers/rst/states.py:
+
+  - Apply [ 1994493 ] Patch to support all kinds of quotes in inline markup.
+  - Added support for Unicode inline markup delimiters "‐ ‑ ‒ – —" and
+    " " (non-breaking space), and "¡ ¿" openers.
+
+* docutils/parsers/directives/misc.py:
+
+  - Added ``start-line`` and ``end-line`` options to "include"
+    directive to select a range of lines.
+  - Hard tabs in literal inclusions are replaced by spaces. This is
+    configurable via the new ``tab-width`` option of the "include" directive
+    (a negative tab-width prevents tab expansion).
+
+* docutils/utils.py:
+
+  - Add ``get_stylesheet_list`` function.
+  - Apply [ 2834836 ] print info at halt
+
+* docutils/transforms/universal.py:
+
+  - Raise default priority of StripClasses to exclude stripped classes from
+    the ToC.
+
+* docutils/writers/html4css1/__init__.py:
+
+  - ``--stylesheet`` and ``--stylesheet-path`` options support a comma
+    separated list of stylesheets.
+  - Address [ 1938891 ] Inline literal text creates "pre" span only when
+    needed to prevent inter-word line wraps.
+  - Use `translate` method instead of repeated `replace` calls.
+  - Fix [ 1757105 ] New ``table-style`` option. Added to standard table
+    classes to allow CSS styling that does not interfere with other
+    table-using constructs (field lists, citations, ...).
+
+* docutils/writers/newlatex2e/__init__.py:
+
+  - Apply [ 1612821 ] Double quotes in literal text in Italian/German
+
+* docutils/writers/latex2e/__init__.py (see also
+  ``__) :
+
+  - Add ``--embed-stylesheet`` option.
+  - Apply [ 1474017 ] image vertical alignment is reversed.
+  - Apply [ 2051599 ] multi-page tables in latex writer (from pabigot).
+  - Change: has_key for dictionaries (not Nodes) to in-operator.
+  - Merge adjacent citations into one latex cite command.
+  - Failsave implementation of custom roles. LaTeX compilation now ignores
+    unknown classes instead of aborting with an error.
+  - Support custom roles based on standard roles.
+  - LaTeX packages can be used as ``--stylesheet`` arguments without
+    restriction. (A style sheet is now referenced with the ``\usepackage``
+    command, if it ends with ``.sty`` or has no extension.)
+  - Add ``bp`` to lenghts without unit (prevents LaTex errors).
+  - Correctly write length unit ``pt`` as ``bp`` in LaTeX.
+  - Do not convert ``px`` to ``pt`` (``px`` is supported by pdfTeX since
+    2005-02-04 as a configurable length unit).
+  - Do not use fontenc, nor the obsolete 'ae' and 'aeguill' packages
+    if font-encoding is set to ''. LaTeX defaults to OT1 then.
+  - Set sub- and superscript role argument in text mode not as math.
+    Use a custom role based on sub-/superscript if you want italic shape.
+  - Shorter preamble and less dependencies: Load packages and define macros
+    only if required in the document.
+  - Use the name prefix ``DU`` for all Docutils specific LaTeX macros.
+  - New custom environments and commands with optional "classes" argument.
+  - Simpler LaTeX encoding, e.g. "\%" instead of "{\%}".
+  - Better conformance to Docutils specifications with ``--use-latex-toc``.
+    Support for LaTeX generated ToC also with unnumbered sections.
+  - If 'sectnum_xform' is False, the 'sectnum' directive triggers
+    section numbering by LaTeX.
+  - Use default font in admonitions and sidebar.
+  - Align of image in a figure defaults to 'center'.
+  - Bugfix: Newlines around targets and references prevent run-together
+    paragraphs.
+  - Fix internal hyperlinks.
+  - Use class defaults for page margins ('typearea' now optional).
+  - Float placement made configurable, default changed to "here definitely".
+  - Typeset generic topic as "quote block with title".
+  - Use template (file and configuration option).
+  - In the default template, load cmap.sty (fix text extraction in PDF) and
+    fixltx2e.sty (LaTeX patches, \textsubscript).
+  - Render doctest blocks as literal blocks (fixes [ 1586058 ]).
+  - Use `translate` instead of repeated `replace` calls for text encoding.
+  - Hyperlinked footnotes and support for symbol footnotes and
+    ``--footnote-references=brackets`` with ``--use-latex-footnotes``.
+  - Complete pairs of binary options
+    (``--figure-footnotes, --figure-citations, --link-stylesheet``,
+    ``--use-docutils-toc, --use-docutils-docinfo, --topic-abstract``)
+  - New defaults:
+    - font-encoding: "T1" (formerly implicitely set by 'ae').
+    - use-latex-toc: true (ToC with page numbers).
+    - use-latex-footnotes: true (no mixup with figures).
+
+* docutils/writers/manpage.py
+
+  - Do not print version at document end, this is done by the viewer.
+  - Do not print date at document end, this is done by the viewer.
+  - Fix storage of docinfo fields for none standard fields.
+
+* docutils/tools/rst2man.py
+
+Release 0.5 (2008-06-25)
+========================
+
+* docutils/languages/he.py: Added to project: Hebrew mappings by
+  Meir Kriheli.
+
+* docutils/parsers/rst/languages/he.py: Added to project: Hebrew
+  mappings by Meir Kriheli.
+
+* docutils/frontend.py:
+
+  - Configuration files are now assumed and required to be
+    UTF-8-encoded.
+  - Paths of applied configuration files are now recorded in the
+    runtime setting ``_config_files`` (accessible via
+    ``--dump-settings``).
+  - Added ``--strip-elements-with-class`` and ``--strip-class``
+    options (``strip_elements_with_classes`` and ``strip_classes``
+    settings).
+
+* docutils/io.py:
+
+  - Added code to determine the input encoding from data: encoding
+    declarations or the presence of byte order marks (UTF-8 & UTF-16).
+  - Added support for IronPython 1.0.
+
+* docutils/nodes.py:
+
+  - Added ``document.__getstate__`` method, for pickling.
+
+* docutils/parsers/rst/states.py:
+
+  - Allow ``+`` and ``:`` in reference names.
+  - Unquoted targets beginning with an underscore (``.. __target:
+    URI``) are no longer accepted.
+  - Added support for multiple attributions in a physical block quote
+    (indented text block), dividing it into multiple logical block
+    quotes.
+  - Added support for unicode bullets in bullet lists: "•", "‣", and
+    "⁃".
+  - Added support for new object-oriented directive interface,
+    retaining compatibility to the old functional interface.
+  - Added support for throwing ``DirectiveError``'s from within
+    directive code.
+
+* docutils/parsers/rst/__init__.py:
+
+  - Added ``Directive`` base class.
+  - Added ``DirectiveError`` base class.
+  - Fixed ``file_insertion_enabled`` & ``raw_enabled`` setting
+    definitions.
+
+* docutils/parsers/directives/:
+
+  - Refactored all reStructuredText directives to use the new
+    object-oriented directive interface.  Errors are now (mostly)
+    thrown using the new ``DirectiveError`` class.
+
+* docutils/parsers/directives/misc.py:
+
+  - Added ``start-after`` and ``end-before`` options to ``include``
+    directive; thanks to Stefan Rank.
+
+* docutils/transforms/universal.py:
+
+  - Added ``StripClassesAndElements`` transform to remove from the
+    document tree all elements with classes in
+    ``settings.strip_elements_with_classes`` and all "classes"
+    attribute values in ``self.document.settings.strip_classes``.
+
+* docutils/transforms/writer_aux.py:
+
+  - Added ``Admonitions`` transform to transform specific admonitions
+    (like ``note``, ``warning``, etc.) into generic admonitions with a
+    localized title.
+
+* docutils/writers/html4css1/__init__.py:
+
+  - Moved template functionality from the PEP/HTML writer here.
+  - Expanded the fragments available in the ``parts`` attribute.
+  - Moved ``id`` attributes from titles to surrounding ``div``
+    elements.
+  - Dropped all ``name`` attributes of ``a`` elements (``id`` is
+    universally supported now).
+  - ``template.txt`` is now opened in text mode instead of binary mode
+    (to ensure Windows compatibility).
+  - ``a`` elements now have an "internal" or "external" class,
+    depending on reference type.
+
+* docutils/writers/html4css1/template.txt: Added to project.
+
+* docutils/writers/pep_html/:
+
+  - Moved template functionality to the HTML writer.
+
+* docutils/writers/s5_html/__init__.py:
+
+  - Added ``view_mode`` & ``hidden_controls`` settings
+    (``--view-mode`` & ``--hidden-controls/--visible-controls``
+    options).
+
+* docutils/writers/latex2e/__init__.py:
+
+  - Add ``--literal-block-env``
+  - Fix: escaping ``%`` in href urls.
+  - Move usepackage hyperref after stylesheet inclusion.
+  - Fix: scrartcl does not have chapter but scrreprt.
+  - Add newline after ``\end{verbatim}``.
+  - Merge smaller differences from latex2e_adaptive_preamble.
+  - Add ``use-part-section``.
+  - Put leavevmode before longtable to avoid having it moved before sub/pargraph.
+  - Using leavemode option_list no longer needs to check if parent
+    is a definition list.
+  - Append ``\leavemode`` to definition list terms.
+  - No longer write visit\_/depart_definition_list_item comments to
+    output.
+  - Table column width with 3 decimal places.
+  - Add table stubs support (boldfont).
+  - Add assemble_parts to writer.
+  - Add simply support for nested tables.
+  - Fix verbatim in tables if use-verbatim-when-possible.
+  - Use section commands down to subparagraph.
+  - Put ensuremath around some latin1 chars.
+  - Set ``usepackage[utf8x]{inputenc}`` for utf-8.
+  - New option ``--use-bibtex=style,db1,db2``.
+  - New option ``--reference-label`` to allow usage of LaTeX ref for
+    labels in section references.
+  - Add a label after every section to support sectionnumbers as reference
+    labels.
+  - Fix: bug# 1605376 rst2latex: bad options group list
+  - Remove inactive code for use_optionlist_for_option_list.
+  - Remove latex comments from option_list output.
+  - Fix: bug# 1612270 double qoutes in italian literal.
+  - Fix: output ``hypertarget{ node.get(refid) }{}`` from visit_target.
+  - Add option --use-latex-abstract.
+  - Image width unit ``px`` is translated to ``pt``.
+  - Add image height support.
+  - Fix: image width ``70%`` is converted ``0.700\linewidth``.
+    bug #1457388
+  - Fix: Do not escape underscores in citation reference labels if
+    use-latex-citations is set.
+  - Use centering instead of center for figure contents, to avoid vertical
+    space.
+  - Recognize table class: borderless, nolines, booktabs, standard.
+  - Fix: Renaming contents section does not work with latex writer; SF
+    bug #1487405.
+  - Applied patch for custom roles with classes from Edward Loper.
+  - Fixed bug that caused crashes with more than 256 lists.
+
+* docutils/writers/pep_html/__init__.py:
+
+  - Changed to support new python.org website structure and
+    pep2pyramid.py.
+
+* docs/howto/security.txt: "Deploying Docutils Securely", added to
+  project.
+
+* tools/buildhtml.py:
+
+  -- Added ``ignore`` setting to exclude a list of shell patterns
+     (default: ``.svn:CVS``).
+
+* tools/editors/emacs/rst.el:
+
+  - Changed license to "GPL".
+  - Added ``rst-straighten-decorations`` function.
+  - The ``compile`` module is now always loaded.
+  - Added ``rst-toggle-line-block`` function.
+  - Headings consisting only of non-ASCII characters are now
+    recognized by ``rst-toc`` and ``rst-adjust``.
+  - Added font-lock support for multi-line comments where the first
+    comment line is empty.
+  - Added ``(require 'font-lock)``.
+
+* setup.py:
+
+  - Provide descriptive error message if distutils is missing.
+
+
+Release 0.4 (2006-01-09)
+========================
+
+* General:
+
+  - Updated the project policies for trunk/branch development &
+    version numbering.
+
+* docutils/__init__.py:
+
+  - Added ``__version_details__`` attribute to describe code source
+    (repository/snapshot/release).
+  - Replaced ``default_transforms`` attribute of TransformSpec with
+    ``get_transforms()`` method.
+
+* docutils/core.py:
+
+  - Added ``publish_doctree`` and ``publish_from_doctree`` convenience
+    functions, for document tree extraction and reprocessing.
+
+* docutils/io.py:
+
+  - Added ``DocTreeInput`` class, for reprocessing existing documents.
+  - Added support for non-Unicode (e.g. binary) writer output.
+
+* docutils/nodes.py:
+
+  - Re-introduced ``Targetable.indirect_reference_name``, for
+    MoinMoin/reST compatibility (removed in r3124/r3129).
+  - Added ``serial_escape`` function; escapes string values that are
+    elements of a list, for serialization.  Modified Docutils-XML
+    writing (``Element._dom_node``) and pseudo-XML writing
+    (``Element.starttag``) to use ``serial_escape``.
+  - Added ``Node.deepcopy()`` method.
+  - Removed the internal lists ``document.substitution_refs``,
+    ``document.anonymous_refs``, and ``document.anonymous_targets``.
+  - Added a "container" element.
+  - Fixed bug where values of list-valued attributes of elements
+    originating from custom interpreted text roles (i.e., with custom
+    classes) were being shared between element instances.  Reported by
+    Shmuel Zeigerman.
+
+* docutils/statemachine.py:
+
+  - Added trailing whitespace stripping to ``string2lines()``.
+  - Added ``StringList.pad_double_width()`` & ``.replace()`` for East
+    Asian double-width character support.
+
+* docutils/utils.py:
+
+  - Added ``east_asian_column_width()`` for double-width character
+    support.
+
+* docutils/languages/ja.py: Added to project: Japanese mappings by
+  Hisashi Morita.
+
+* docutils/languages/zh_cn.py: Added to project: Simplified Chinese
+  mappings by Panjunyong.
+
+* docutils/parsers/null.py: Added to project; a do-nothing parser.
+
+* docutils/parsers/rst/__init__.py:
+
+  - Added validator to tab_width setting, with test.  Closes SF bug
+    #1212515, report from Wu Wei.
+
+* docutils/parsers/rst/states.py:
+
+  - Fixed bug with escaped colons indicating a literal block.
+  - Fixed bug with enumerated lists (SF#1254145).
+  - Backslash-escaped colons inside of field names are now allowed.
+  - Targets (implicit and explicit), anonymous hyperlink references
+    and auto-numbered footnote references inside of substitution
+    definitions are now disallowed.
+  - Fixed bug: list items with blank first lines.
+  - Fixed bug: block quote attributions with indented second lines.
+  - Added East Asian double-width character support (Python 2.4 only).
+
+* docutils/parsers/rst/tableparser.py:
+
+  - Added East Asian double-width character support (Python 2.4 only).
+
+* docutils/parsers/rst/directives/body.py:
+
+  - Added the "container" directive.
+
+* docutils/parsers/rst/directives/misc.py:
+
+  - Added the "default-role", "title", and "date" directives.
+  - Added standard data file syntax to the "include" directive.
+  - Added support for "class" directive content.
+
+* docutils/parsers/rst/directives/images.py:
+
+  - Added ``indirect_reference_name`` support for images with a target
+    option.
+  - Added support for image width and height units.
+  - Fixed bug with image "target" options.
+
+* docutils/parsers/rst/directives/references.py:
+
+  - Added "class" attribute to "target-notes" directive, for
+    footnote_reference classes.
+
+* docutils/parsers/rst/include/: Directory added to project; contains
+  standard data files for the "include" directive.  Initial contents:
+  character entity substitution definition sets, and a set of
+  definitions for S5/HTML presentations.
+
+* docutils/parsers/rst/languages/ja.py: Added to project: Japanese
+  mappings by David Goodger.
+
+* docutils/parsers/rst/languages/zh_cn.py: Added to project:
+  Simplified Chinese mappings by Panjunyong.
+
+* docutils/readers/__init__.py:
+
+  - Added universal.Decorations and universal.ExposeInternals
+    transforms as default transforms for all readers.
+  - Added ``ReReader`` base class for readers that reread an existing
+    document tree.
+
+* docutils/readers/doctree.py: Added to project; a reader for existing
+  document trees.
+
+* docutils/transforms/frontmatter.py:
+
+  - Fixed the DocInfo transform to handle SVN-style expansion of the
+    "Date" keyword.
+  - In ``DocInfo.extract_authors``, treat the contents of "authors"
+    fields uniformly.
+
+* docutils/transforms/misc.py:
+
+  - Added misc.Transitions transform, extracted from
+    universal.FinalChecks.
+
+* docutils/transforms/references.py:
+
+  - Added references.DanglingReferences transform, extracted from
+    universal.FinalChecks.
+  - Fixed bug with doubly-indirect substitutions.
+  - Added footnote_reference classes attribute to "TargetNotes".
+  - Fixed bug with circular substitution definitions that put Docutils
+    into an infinite loop.
+
+* docutils/transforms/universal.py:
+
+  - Added universal.ExposeInternals transform, extracted from
+    universal.FinalChecks.
+  - Removed universal.FinalChecks transform (logic has been moved to
+    several new transforms).
+  - Fixed bug with the "expose_internals" setting and Text nodes
+    (exposed by the "rawsource" internal attribute).
+  - Added the universal.StripComments transform, implementation of the
+    "strip_comments" setting.
+
+* docutils/transforms/writer_aux.py: Added to project; auxiliary
+  transforms for writers.
+
+  - Added ``Compound`` transform, which flattens compound paragraphs.
+
+* docutils/writers/: Several writer modules (html4css1.py) were
+  converted into packages.  Support modules and data files have been
+  moved into the packages.  The stylesheets for the HTML writers are
+  now installed along with the code, the code knows where to find
+  them, and the default is to use them (actually, to embed them).
+  Some adjustments to configuration files may be necessary.  The
+  easiest way to obtain the new default behavior is to remove all
+  settings whose name includes "stylesheet".
+
+* docutils/writers/__init__.py:
+
+  - Added universal.Messages and universal.FilterMessages transforms
+    as default transforms for all writers.
+  - Added ``UnfilteredWriter`` base class for writers that pass the
+    document tree on unchanged.
+
+* docutils/writers/docutils_xml.py:
+
+  - Made ``xmlcharrefreplace`` the default output encoding error
+    handler.
+
+* docutils/writers/html4css1/:
+
+  - Added support for image width and height units.
+  - Made ``xmlcharrefreplace`` the default output encoding error
+    handler.
+  - Made ``--embed-stylesheet`` the default rather than
+    ``--link-stylesheet``.
+  - Moved "id" attribute from container (section etc.) to title's 
+    tag, to be on the same tag as "name".
+    (!!! To be reverted in Docutils 0.5.)
+  - Added vertical space between fields of field lists.
+  - Added ``--compact-field-lists`` option to remove vertical space in
+    simple field lists.
+  - Made cloaking of email addresses with ``--cloak-email-addresses``
+    less obtrusive.
+  - Fixed support for centered images.
+  - Added support for class="compact" & class="open" lists.
+
+* docutils/writers/latex2e/:
+
+  - Underscores in citekeys are no longer escaped.
+
+* docutils/writers/newlatex2e/unicode_map.py: Added to project;
+  mapping of Unicode characters to LaTeX equivalents.
+
+* docutils/writers/s5_html/: Package added to project; writer for
+  S5/HTML slide shows.
+
+* docs/dev/distributing.txt: Added to project; guide for distributors
+  (package maintainers).
+
+* docs/dev/hacking.txt: Added to project; guide for developers.
+
+* docs/ref/doctree.txt:
+
+  - Updated for plural attributes "classes", "ids", "names",
+    "dupnames".
+  - Added the "container" element.
+
+* docs/ref/docutils.dtd:
+
+  - Updated for plural attributes "classes", "ids", "names",
+    "dupnames".
+
+* docs/user/emacs.txt: Added to project; a document about Emacs
+  support for reStructuredText and Docutils.
+
+* docs/user/links.txt: Added to project; lists of Docutils-related
+  links.
+
+* docs/user/mailing-lists.txt: Added to project; information about
+  Docutils-related mailing lists and how to access them.
+
+* docs/user/slide-shows.txt: Added to project; example of and docs for
+  the S5/HTML writer (``rst2s5.py`` front end).
+
+* docs/ref/rst/definitions.txt: "reStructuredText Standard Definition
+  Files", added to project.
+
+* test/coverage.sh: Added to project; test coverage script.
+
+* test/DocutilsTestSupport.py:
+
+  - Added support for specifying runtime settings at the suite level.
+
+* test/test_functional.py:
+
+  - Added the ``clear_output_directory`` function.
+  - Added support for ``_test_more`` functions in functional test
+    config files.
+
+* tools/rst2s5.py: Added to project; front end for the S5/HTML writer.
+
+* tools/rstpep2html.py: Renamed from pep.py.
+
+* tools/dev/create_unimap.py: Added to project; script to create the
+  docutils/writers/unimap_latex.py mapping file.
+
+* tools/dev/profile_docutils.py: Added to project; profiler script.
+
+* tools/dev/unicode2rstsubs.py: Moved from tools/unicode2rstsubs.py.
+
+* tools/editors/emacs/restructuredtext.el,
+  tools/editors/emacs/rst-html.el, tools/editors/emacs/rst-mode.el:
+  Removed from project; the functionality is now contained in rst.el.
+
+* tools/editors/emacs/rst.el: Added to project.  Added many features
+  and fixed many bugs.  See docs/user/emacs.txt for details.
+
+* tools/stylesheets: Removed from project.  Stylesheets have been
+  renamed and moved into writer packages.
+
+
+Release 0.3.9 (2005-05-26)
+==========================
+
+* General:
+
+  - Eliminated and replaced all uses of the old string attributes
+    ``id``, ``name``, ``dupname`` and ``class`` with references to the
+    new list attributes ``ids``, ``names``, ``dupnames`` and
+    ``classes`` throughout the whole source tree.
+
+* docutils/core.py:
+
+  - Enabled ``--dump-*`` options when ``--traceback`` specified,
+    allowing for easier debugging.
+  - In ``Publisher.publish()``, expanded the generic top-level
+    exception catching.
+
+* docutils/examples.py:
+
+  - Added ``internals`` function for exploration.
+
+* docutils/io.py:
+
+  - Fixed ``Input.decode`` method to apply heuristics only if no
+    encoding is explicitly given, and to provide better reporting of
+    decoding errors.
+  - The ``Input.decode`` method now removes byte order marks (BOMs)
+    from input streams.
+
+* docutils/nodes.py:
+
+  - ``image`` element class changed to subclass of Element, not
+    TextElement (it's an empty element, and cannot contain text).
+  - Added ``attr_defaults`` dictionary for default attribute values.
+  - Added empty list as default value for the following attributes:
+    ``ids``, ``names``, ``dupnames``, ``classes``, and ``backrefs``.
+  - Added ``document.decoration`` attribute,
+    ``document.get_decoration`` method, and ``decoration.get_header``
+    & ``.get_footer`` methods.
+  - Added ``Element.update_basic_atts()`` and ``Element.substitute()``
+    methods.
+
+* docutils/utils.py:
+
+  - Removed ``docutils.utils.Reporter.categories``,
+    ``docutils.utils.ConditionSet``, and all references to them, to
+    simplify error reporting.
+
+* docutils/languages/nl.py: Added to project; Dutch mappings by
+  Martijn Pieters.
+
+* docutils/parsers/rst/__init__.py:
+
+  - Added settings: ``file_insertion_enabled`` & ``raw_enabled``.
+
+* docutils/parsers/rst/states.py:
+
+  - Added check for escaped at-mark to prevent email address recognition.
+  - Fixed option lists to allow spaces inside ````.
+  - Allowed whitespace in paths and URLs.
+  - Added auto-enumerated list items.
+  - Fixed bug that assumed ``.. _`` and ``.. |`` were invariably
+    followed by text.
+  - Added support for table stub columns.
+
+* docutils/parsers/rst/directives/__init__.py:
+
+  - Allowed whitespace in paths (``path`` function).
+  - Added ``uri`` directive option conversion function.
+
+* docutils/parsers/rst/directives/body.py:
+
+  - Fixed illegal context bug with "topic" directive (allowed within
+    sidebars; not within body elements).
+
+* docutils/parsers/rst/directives/images.py:
+
+  - Allowed whitespace (stripped) in "image" & "figure" directive URLs.
+  - Added support for the ``file_insertion_enabled`` setting in the
+    "figure" directive (disables "figwidth" option).
+  - "image" directive: added checks for valid values of "align" option,
+    depending on context.  "figure" directive: added specialized
+    "align" option and attribute on "figure" element.
+  - Made ":figwidth: image" option of "figure" directive work again.
+  - Fixed bug with reference names containing uppercase letters
+    (e.g. ``Name_``) in "target" option of "image" directive.
+
+* docutils/parsers/rst/directives/misc.py:
+
+  - Fixed "include" and "raw" directives to catch text decoding
+    errors.
+  - Allowed whitespace in "include" & "raw" directive paths.
+  - Added support for ``file_insertion_enabled`` & ``raw_enabled``
+    settings in "include" & "raw" directives.
+
+* docutils/parsers/rst/directives/parts.py:
+
+  - Added "header" & "footer" directives.
+  - Fixed illegal context bug with "contents" directive (topics
+    allowed within sidebars; not within body elements).
+
+* docutils/parsers/rst/directives/tables.py:
+
+  - Added "list-table" directive.
+  - Caught empty CSV table bug.
+  - Added support for the ``file_insertion_enabled`` setting in the
+    "csv-table" directive.
+  - Added ``stub-columns`` option to "csv-table" and "list-table"
+    directives.
+
+* docutils/parsers/rst/languages/nl.py: Added to project; Dutch
+  mappings by Martijn Pieters.
+
+* docutils/readers/standalone.py:
+
+  - Added ``--section-subtitles`` and ``--no-section-subtitles``
+    options to activate or deactivate the SectSubTitle transform.
+
+* docutils/transforms/frontmatter.py:
+
+  - Added SectSubTitle transform to promote titles of lone
+    subsections to subtitles.
+
+* docutils/transforms/references.py:
+
+  - Fixed mislocated internal targets bug, by propagating internal
+    targets to the next node, making use of the newly added support
+    for multiple names and IDs.
+  - Fixed duplicate footnote label bug.
+  - Replaced ``ChainedTargets`` with more generic ``PropagateTargets``
+    transform.
+
+* docutils/writers/html4css1.py:
+
+  - Fixed unencoded stylesheet reference bug (characters like "&" in
+    stylesheet references).
+  - ``target`` nodes now appear as ``span`` tags (instead of ``a``
+    tags).
+  - Added support for multiple IDs per node by creating empty ``span``
+    tags.
+  - Added the ``field_name_limit`` & ``option_limit`` settings &
+    support.
+  - Added support for table stub columns.
+  - Added support for the ``align`` attribute on ``figure`` elements.
+  - Added the ``cloak_email_addresses`` setting & support.
+  - Added ``html_prolog``, ``html_head``, ``html_body``,
+    ``html_title``, & ``html_subtitle`` to parts dictionary exposed by
+    ``docutils.core.publish_parts``.
+  - Added support for section subtitles.
+
+* docutils/writers/latex2e.py:
+
+  - Fixed tables starting with more than one multirow cell.
+  - Improved --use-latex-docinfo so that organization/contact/address
+    fields are lumped with the last author field and appear on the
+    titlepage.
+  - Made sure the titlepage is always shown with --use-latex-docinfo,
+    even if the document has no title.
+  - Made sure that latex doesn't fill in today's date if no date field
+    was given.
+  - Added support for section subtitles.
+
+* docutils/writers/newlatex2e.py: Added to project; a new LaTeX writer
+  (under development).
+
+* docutils/writers/null.py: Added to project; a do-nothing Writer.
+
+* docs/api/publisher.txt:
+
+  - Added "``publish_parts`` Details" section.
+
+* docutils/dev/repository.txt: Added to project; information about the
+  Docutils Subversion repository.
+
+* docs/ref/docutils.dtd:
+
+  - Added a ``stub`` attribute to the ``colspec`` element via the
+    ``tbl.colspec.att`` parameter entity.
+  - Allowed topic elements within sidebars
+  - Added an ``align`` attribute to the ``figure`` element.
+
+* tools/rst2newlatex.py: Added to project; front end for the new LaTeX
+  writer.
+
+
+Release 0.3.7 (2004-12-24)
+==========================
+
+* docutils/frontend.py:
+
+  - Added options: --input-encoding-error-handler,
+    --record-dependencies, --leave-footnote-reference-space,
+    --strict-visitor.
+  - Added command-line and config file support for "overrides" setting
+    parameter.
+
+* docutils/io.py:
+
+  - Added support for input encoding error handler.
+
+* docutils/nodes.py:
+
+  - Added dispatch_visit and dispatch_departure methods to
+    NodeVisitor; useful as a hook for Visitors.
+  - Changed structure of ``line_block``; added ``line``.
+  - Added ``compound`` node class.
+  - Added a mechanism for Visitors to transitionally ignore new node
+    classes.
+
+* docutils/utils.py:
+
+  - Moved ``escape2null`` and ``unescape`` functions from
+    docutils/parsers/rst/states.py.
+
+* docutils/parsers/rst/roles.py:
+
+  - Added "raw" role.
+  - Changed role function API: the "text" parameter now takes
+    null-escaped interpreted text content.
+
+* docutils/parsers/rst/states.py:
+
+  - Fixed bug where a "role" directive in a nested parse would crash
+    the parser; the state machine's "language" attribute was not being
+    copied over.
+  - Added support for line block syntax.
+  - Fixed directive parsing bug: argument-less directives didn't
+    notice that arguments were present.
+  - Removed error checking for transitions.
+  - Added support for multiple classifiers in definition list items.
+  - Moved ``escape2null`` and ``unescape`` functions to docutils/utils.py.
+  - Changed role function API: the "text" parameter now takes
+    null-escaped interpreted text content.
+  - Empty sections and documents are allowed now.
+
+* docutils/parsers/rst/directives/__init__.py:
+
+  - Added ``encoding`` directive option conversion function.
+  - Allow multiple class names in class_option conversion function.
+
+* docutils/parsers/rst/directives/body.py:
+
+  - Converted the line-block directive to use the new structure.
+  - Extracted the old line-block functionality to the ``block``
+    function (still used).
+  - Added ``compound`` directive (thanks to Lea Wiemann).
+
+* docutils/parsers/rst/directives/misc.py:
+
+  - Added "encoding" option to "include" and "raw" directives.
+  - Added "trim", "ltrim", and "rtrim" options to "unicode" directive.
+  - Allow multiple class names in the "class" directive.
+
+* docutils/parsers/rst/directives/parts.py:
+
+  - Directive "sectnum" now accepts "prefix", "suffix", and "start"
+    options.  Thanks to Lele Gaifax.
+
+* docutils/parsers/rst/directives/tables.py:
+
+  - Added "encoding" directive to "csv-table" directive.
+  - Added workaround for lack of Unicode support in csv.py, for
+    non-ASCII CSV input.
+
+* docutils/transforms/misc.py:
+
+  - Fixed bug when multiple "class" directives are applied to a single
+    element.
+  - Enabled multiple format names for "raw" directive.
+
+* docutils/transforms/references.py:
+
+  - Added support for trimming whitespace from beside substitution
+    references.
+
+* docutils/transforms/universal.py:
+
+  - FinalChecks now checks for illegal transitions and moves
+    transitions between sections.
+
+* docutils/writers/html4css1.py:
+
+  - HTMLTranslator.encode now converts U+00A0 to " ".
+  - "stylesheet" and "stylesheet_path" settings are now mutually
+    exclusive.
+  - Added support for the new line_block/line structure.
+  - --footnote-references now overrides
+    --trim-footnote-reference-space, if applicable.
+  - Added support for ``compound`` elements.
+  - Enabled multiple format names for "raw" directive.
+  - ``

`` tags of a paragraph which is the only visible child of the + document node are no longer stripped. + - Moved paragraph-compacting logic (for stripping ``

`` tags) to + new method ``should_be_compact_paragraph()``. + - Added class="docutils" to ``dl``, ``hr``, ``table`` and ``tt`` + elements. + - "raw" elements are now surrounded by ``span`` or ``div`` tags in + the output if they have their ``class`` attribute set. + - The whole document is now surrounded by a ``

`` element. + - Body-level images are now wrapped by their own ``
`` elements, + with image classes copied to the wrapper, and for images which + have the ``:align:`` option set, the surrounding ``
`` now + receives a class attribute (like ``class="align-left"``). + +* docutils/writers/latex2e.py: + + - no newline after depart_term. + - Added translations for some Unicode quotes. + - Added option "font-encoding", made package AE the default. + - "stylesheet" and "stylesheet_path" settings are now mutually + exclusive. + - --footnote-references now overrides + --trim-footnote-reference-space, if applicable. + - The footnote label style now matches the footnote reference style + ("brackets" or "superscript"). + - Added support for ``compound`` elements. + - Enabled multiple format names for "raw" directive. + +* docs/ref/docutils.dtd: + + - Changed structure of the ``line_block`` element; added ``line``. + - Added ``compound`` element. + - Added "ltrim" and "rtrim" attributes to + ``substitution_definition`` element. + - Enabled multiple format names for ``raw`` element. + - Enabled multiple classifiers in ``definition_list_item`` elements. + +* docs/ref/rst/directives.txt + + - Marked "line-block" as deprecated. + - "Class" directive now allows multiple class names. + - Added "Rationale for Class Attribute Value Conversion". + - Added warning about "raw" overuse/abuse. + +* docs/ref/rst/restructuredtext.txt: + + - Added syntax for line blocks. + - Definition list items may have multiple classifiers. + +* docs/ref/rst/roles.txt: + + - Added "raw" role. + +* tools/stylesheets/default.css: + + - Added support for the new line_block structure. + - Added "docutils" class to ``dl``, ``hr``, ``table`` and ``tt``. + + +Release 0.3.5 (2004-07-29) +========================== + +General: + +* _`Documentation cleanup/reorganization`. + + - Created new subdirectories of docs/: + + * ``docs/user/``: introductory/tutorial material for end-users + * ``docs/dev/``: for core-developers (development notes, plans, etc.) + * ``docs/api/``: API reference material for client-developers + * ``docs/ref/``: reference material for all groups + * ``docs/howto/``: for component-developers and core-developers + * ``docs/peps/``: Python Enhancement Proposals + + - Moved ``docs/*`` to ``docs/user/``. + - Moved ``pysource.dtd``, ``pysource.txt``, ``semantics.txt`` from + ``spec/`` to ``docs/dev``. + - Moved ``doctree.txt``, ``docutils.dtd``, ``soextblx.dtd``, + ``transforms.txt`` from ``spec/`` to ``docs/ref/``. + - Moved ``alternatives.txt``, and ``problems.txt`` from + ``spec/rst/`` to ``docs/dev/rst/``. + - Moved ``reStructuredText.txt``, ``directives.txt``, + ``interpreted.txt``, and ``introduction.txt`` from ``spec/rst/`` + to ``docs/ref/rst/``. Renamed ``interpreted.txt`` to + ``roles.txt``, ``reStructuredText.txt`` to + ``restructuredtext.txt``. + - Moved ``spec/howto/`` to ``docs/howto``. + + In order to keep the CVS history of moved files, we supplied + SourceForge with a `script for modifying the Docutils CVS + repository`__. + + __ http://cvs.sourceforge.net/viewcvs.py/*checkout*/docutils/sandbox/davidg/infrastructure/cvs-reorg.sh?content-type=text/plain&rev=1.5 + + After running the cleanup script: + + - Added ``docs/index.txt``. + - Added a ``.htaccess`` file to the ``web`` module, containing + redirects for all old paths to new paths. They'll preserve + fragments (the "#name" part of a URL), and won't clutter up the + file system, and will correct the URL in the user's browser. + - Added ``BUGS.txt``, ``docs/dev/policies.txt``, + ``docs/dev/website.txt``, ``docs/dev/release.txt`` from all but + the "To Do" list itself in ``docs/dev/todo.txt``. + - Moved "Future Plans" from ``HISTORY.txt`` to new "Priorities" + section of ``docs/dev/todo.txt``. + - Added ``THANKS.txt`` from "Acknowledgements" in ``HISTORY.txt``. + - Added "How To Report Bugs" to ``BUGS.txt``. + - Went through all the sources and docs (including under web/) and + updated links. Mostly done by Lea Wiemann; thanks Lea! + (Still need to update links in the sandboxes.) + +Specific: + +* BUGS.txt: Added to project. + +* THANKS.txt: Added to project. + +* docutils/__init__.py: + + - 0.3.4: Post-release. + +* docutils/core.py: + + - Added special error handling & advice for UnicodeEncodeError. + - Refactored Publisher.publish (simplified exception handling & + extracted debug dumps). + - Renamed "enable_exit" parameter of convenience functions to + "enable_exit_status". + - Enabled traceback (exception propagation) by default in + programmatic convenience functions. + - Now publish_file and publish_cmdline convenience functions return + the encoded string results in addition to their regular I/O. + - Extracted common code from publish_file, publish_string, and + publish_parts, into new publish_programmatically. Extracted + settings code to ``Publisher.process_programmatic_settings``. + - In Publisher.publish, disabled ``settings_overrides`` when + ``settings`` is supplied; redundant. + +* docutils/frontend.py: + + - Added help text for "--output-encoding-error-handler" and + "--error-encoding-error-handler". + - Renamed "--exit" to "--exit-status". + - Simplified default-setting code. + +* docutils/parsers/rst/__init__.py: + + - Added "--pep-base-url" and "--rfc-base-url" options. + +* docutils/parsers/rst/states.py: + + - Made URI recognition more aggressive and intelligent. + +* docutils/parsers/rst/directives/__init__.py: + + - Added several directive option conversion functions. + +* docutils/parsers/rst/directives/body.py: + + - Moved "table" directive to tables.py. + +* docutils/parsers/rst/directives/tables.py: Table-related directives, + added to project. + +* docutils/writers/latex2e.py: + + - Added "--table-style=(standard|booktabs|nolines)" + - figures get "here" option (LaTeX per default puts them at bottom), + and figure content is centered. + - Rowspan support for tables. + - Fix: admonition titles before first section. + - Replace ``--`` in literal by ``-{}-`` because fontencoding T1 has endash. + - Replave ``_`` in literal by an underlined blank, because it has the correct + width. + - Fix: encode pdfbookmark titles, ``#`` broke pdflatex. + - A few unicode replacements, if output_encoding != utf + - Add "--graphicx-option". + - Indent literal-blocks. + - Fix: omit ``\maketitle`` when there is no document title. + +* docs/index.txt: "Docutils Project Documentation Overview", added to + project. + +* docs/api/cmdline-tool.txt: "Inside A Docutils Command-Line Front-End + Tool", added to project. + +* docs/api/publisher.txt: "The Docutils Publisher", added to project. + +* docs/api/runtime-settings.txt: "Docutils Runtime Settings", added to project. + +* docs/dev/policies.txt: Added to project (extracted from + ``docs/dev/todo.txt``, formerly ``spec/notes.txt``). + +* docs/dev/release.txt: Added to project (extracted from + ``docs/dev/todo.txt``, formerly ``spec/notes.txt``). + +* docs/dev/testing.txt: Added to project. + +* docs/dev/website.txt: Added to project (extracted from + ``docs/dev/todo.txt``, formerly ``spec/notes.txt``). + +* docs/ref/rst/directives.txt: + + - Added directives: "table", "csv-table". + +* docs/user/rst/cheatsheet.txt: "The reStructuredText Cheat Sheet" + added to project. 1 page for syntax, and a 1 page reference for + directives and roles. Source text to be used as-is; not meant to be + converted to HTML. + +* docs/user/rst/demo.txt: Added to project; moved from tools/test.txt + with a change of title. + +* test/functional/, contents, and test/test_functional.py: Added to + project. + +* tools/buildhtml.py: Fixed bug with config file handling. + +* tools/html.py: Removed from project (duplicate of rst2html.py). + +* tools/pep2html.py: Removed from project (duplicate of Python's + nondist/peps/pep2html.py; Docutils' tools/pep.py can be used for + Docutils-related PEPs in docs/peps/). + +* tools/rst2pseudoxml.py: Renamed from publish.py. + +* tools/rst2xml.py: Renamed from docutils-xml.py. + +* tools/test.txt: Removed from project; moved to + docs/user/rst/demo.txt. + +* setup.py: Now also installs ``rst2latex.py``. + + +Release 0.3.3 (2004-05-09) +========================== + +* docutils/__init__.py: + + - 0.3.1: Reorganized config file format (multiple sections); see + docs/config.txt. + - Added unknown_reference_resolvers attribute to TransformSpec. + - 0.3.2: Interpreted text reorganization. + - 0.3.3: Released. + +* docutils/core.py: + + - Catch system messages to stop tracebacks from parsing errors. + - Catch exceptions during processing report & exit without + tracebacks, except when "--traceback" used. + - Reordered components for OptionParser; application comes last. + - Added "config_section" parameter to several methods and functions, + allowing front ends to easily specify their config file sections. + - Added publish_parts convenience function to allow access to individual + parts of a document. + +* docutils/examples.py: Added to project; practical examples of + Docutils client code, to be used as-is or as models for variations. + +* docutils/frontend.py: + + - Added "--traceback" & "--no-traceback" options ("traceback" + setting). + - Implemented support for config file reorganization: + ``standard_config_files`` moved from ``ConfigParser`` to + ``OptionParser``; added + ``OptionParser.get_config_file_settings()`` and + ``.get_standard_config_settings()``; support for old "[options]" + section (with deprecation warning) and mapping from old to new + settings. + - Reimplemented setting validation. + - Enabled flexible boolean values: yes/no, true/false, on/off. + - Added ``Values``, a subclass of ``optparse.Values``, with support + for list setting attributes. + - Added support for new ``DOCUTILSCONFIG`` environment variable; + thanks to Beni Cherniavsky. + - Added "--no-section-numbering" option. + +* docutils/io.py: + + - Catch IOErrors when opening source & destination files, report & + exit without tracebacks. Added ``handle_io_errors`` parameter to + ``FileInput`` & ``FileOutput`` to enable caller error handling. + +* docutils/nodes.py: + + - Changed ``SparseNodeVisitor`` and ``GenericNodeVisitor`` dynamic + method definitions (via ``exec``) to dynamic assignments (via + ``setattr``); thanks to Roman Suzi. + - Encapsulated visitor dynamic assignments in a function; thanks to + Ian Bicking. + - Added indirect_reference_name attribute to the Targetable + class. This attribute holds the whitespace_normalized_name + (contains mixed case) of a target. + +* docutils/statemachine.py: + + - Renamed ``StringList.strip_indent`` to ``.trim_left``. + - Added ``StringList.get_2D_block``. + +* docutils/utils.py: + + - Added "level" attribute to SystemMessage exceptions. + +* docutils/languages/af.py: Added to project; Afrikaans mappings by + Jannie Hofmeyr. + +* docutils/languages/cs.py: Added to project; Czech mappings by Marek + Blaha. + +* docutils/languages/eo.py: Added to project; Esperanto mappings by + Marcelo Huerta San Martin. + +* docutils/languages/pt_br.py: Added to project; Brazilian Portuguese + mappings by Lalo Martins. + +* docutils/languages/ru.py: Added to project; Russian mappings by + Roman Suzi. + +* docutils/parsers/rst/roles.py: Added to project. Contains + interpreted text role functions, a registry for interpreted text + roles, and an API for adding to and retrieving from the registry. + Contributed by Edward Loper. + +* docutils/parsers/rst/states.py: + + - Updated ``RSTState.nested_parse`` for "include" in table cells. + - Allowed true em-dash character and "---" as block quote + attribution marker. + - Added support for complex option arguments + (option lists). + - Fixed handling of backslashes in substitution definitions. + - Fixed off-by-1 error with extra whitespace after substitution + definition directive. + - Added inline markup parsing to field lists' field names. + - Added support for quoted (and unindented) literal blocks. + Driven in part by a bribe from Frank Siebenlist (thanks!). + - Parser now handles escapes in URIs correctly. + - Made embedded-URIs' reference text omittable. Idea from Beni + Cherniavsky. + - Refactored explicit target processing code. + - Added name attribute to references containing the reference name only + through whitespace_normalize_name (no case changes). + - parse_target no longer returns the refname after going through + normalize_name. This is now handled in make_target. + - Fixed bug relating to role-less interpreted text in non-English + contexts. + - Reorganized interpreted text processing; moved code into the new + roles.py module. Contributed by Edward Loper. + - Refactored ``Body.parse_directive`` into ``run_directive`` and + ``parse_directive_block``. + +* docutils/parsers/rst/tableparser.py: + + - Reworked for ``StringList``, to support "include" directives in + table cells. + +* docutils/parsers/rst/directives/__init__.py: + + - Renamed ``unchanged()`` directive option conversion function to + ``unchanged_required``, and added a new ``unchanged``. + - Catch unicode value too high error; fixes bug 781766. + - Beefed up directive error reporting. + +* docutils/parsers/rst/directives/body.py: + + - Added basic "table" directive. + +* docutils/parsers/rst/directives/images.py: + + - Added "target" option to "image" directive. + - Added name attribute to references containing the reference name only + through whitespace_normalize_name (no case changes). + +* docutils/parsers/rst/directives/misc.py: + + - Isolated the import of the ``urllib2`` module; was causing + problems on SourceForge (``libssl.so.2`` unavailable?). + - Added the "role" directive for declaring custom interpreted text + roles. + +* docutils/parsers/rst/directives/parts.py: + + - The "contents" directive does more work up-front, creating the + "topic" and "title", and leaving the "pending" node for the + transform. Allows earlier reference resolution; fixes subtle bug. + +* docutils/parsers/rst/languages/af.py: Added to project; Afrikaans + mappings by Jannie Hofmeyr. + +* docutils/parsers/rst/languages/cs.py: Added to project; Czech + mappings by Marek Blaha. + +* docutils/parsers/rst/languages/eo.py: Added to project; Esperanto + mappings by Marcelo Huerta San Martin. + +* docutils/parsers/rst/languages/pt_br.py: Added to project; Brazilian + Portuguese mappings by Lalo Martins. + +* docutils/parsers/rst/languages/ru.py: Added to project; Russian + mappings by Roman Suzi. + +* docutils/transforms/parts.py: + + - The "contents" directive does more work up-front, creating the + "topic" and "title", and leaving the "pending" node for the + transform. Allows earlier reference resolution; fixes subtle bug. + - Added support for disabling of section numbering. + +* docutils/transforms/references.py: + + - Verifying that external targets are truly targets and not indirect + references. This is because we are now adding a "name" attribute to + references in addition to targets. Note sure if this is correct! + - Added code to hook into the unknown_reference_resolvers list for a + transformer in resolve_indirect_target. This allows the + unknown_reference_resolvers to keep around indirect targets which + docutils doesn't know about. + - Added specific error message for duplicate targets. + +* docutils/transforms/universal.py: + + - Added FilterMessages transform (removes system messages below the + verbosity threshold). + - Added hook (via docutils.TransformSpec.unknown_reference_resolvers) + to FinalCheckVisitor for application-specific handling of + unresolvable references. + - Added specific error message for duplicate targets. + +* docutils/writers/__init__.py: + + - Added assemble_parts method to the Writer class to allow for + access to a documents individual parts. + - Documented & set default for ``Writer.output`` attribute. + +* docutils/writers/html4css1.py: + + - Fixed unicode handling of attribute values (bug 760673). + - Prevent duplication of "class" attribute values (bug report from + Kirill Lapshin). + - Improved table grid/border handling (prompted by report from Bob + Marshall). + - Added support for table titles. + - Added "" for untitled docs, for XHTML conformance; thanks + to Darek Suchojad. + - Added functionality to keep track of individual parts of a document + and store them in a dictionary as the "parts" attribute of the writer. + Contributed by Reggie Dugard at the Docutils sprint at PyCon DC 2004. + - Added proper support for the "scale" attribute of the "image" + element. Contributed by Brent Cook. + - Added ``--initial-header-level`` option. + - Fixed bug: the body_pre_docinfo segment depended on there being a + docinfo; if no docinfo, the document title was incorporated into + the body segment. Adversely affected the publish_parts interface. + +* docutils/writers/latex2e.py: + + - Changed default stylesheet to "no stylesheet" to avoid latex complaining + about a missing file. + - Added options and support: ``--compound-enumerators``, + ``--section-prefix-for-enumerators``, and + ``--section-enumerator-separator``. By John F Meinel Jr (SF patch + 934322). + - Added option ``--use-verbatim-when-possible``, to avoid + problematic characters (eg, '~' in italian) in literal blocks. + - It's now possible to use four section levels in the `book` and + `report` LaTeX classes. The default `article` class still has + three levels limit. + +* docs/config.txt: "Docutils Configuration Files", added to project. + Moved config file entry descriptions from tools.txt. + +* docs/tools.txt: + + - Moved config file entry descriptions to config.txt. + +* spec/notes.txt: Continual updates. Added "Setting Up For Docutils + Development". + +* spec/howto/rst-roles.txt: "Creating reStructuredText Interpreted + Text Roles", added to project. + +* spec/rst/reStructuredText.txt: + + - Added description of support for <angle-bracketed> complex option + arguments to option lists. + - Added subsections for indented and quoted literal blocks. + +* test: Continually adding & updating tests. + + - Added test/test_settings.py & test/data/config_*.txt support + files. + - Added test/test_writers/test_htmlfragment.py. + +* test/DocutilsTestSupport.py: + + - Refactored LaTeX publisher test suite/case class names to make + testing other writers easier. + - Added HtmlWriterPublishTestCase and HtmlFragmentTestSuite classes + to test the processing of HTML fragments which use the new + publish_parts convenience function. + +* tools/buildhtml.py: + + - Added support for the "--prune" option. + - Removed dependency on pep2html.py; plaintext PEPs no longer + supported. + +* tools/docutils.conf: + + - Updated for configuration file reorganization. + +* tools/rst2html.py: + + - copied from tools/html.py + +* setup.py: + + - added a 'scripts' section to configuration + - added 'tools/rst2html.py' to the scripts section + + +Release 0.3 (2003-06-24) +======================== + +General: + +* Renamed "attribute" to "option" for directives/extensions. + +* Renamed transform method "transform" to "apply". + +* Renamed "options" to "settings" for runtime settings (as set by + command-line options). Sometimes "option" (singular) became + "settings" (plural). Some variations below: + + - document.options -> document.settings (stored in other objects as + well) + - option_spec -> settings_spec (not directives though) + - OptionSpec -> SettingsSpec + - cmdline_options -> settings_spec + - relative_path_options -> relative_path_settings + - option_default_overrides -> settings_default_overrides + - Publisher.set_options -> Publisher.get_settings + +Specific: + +* COPYING.txt: Added "Public Domain Dedication". + +* FAQ.txt: Frequently asked questions, added to project. + +* setup.py: + + - Updated with PyPI Trove classifiers. + - Conditional installation of third-party modules. + +* docutils/__init__.py: + + - Bumped version to 0.2.1 to reflect changes to I/O classes. + - Bumped version to 0.2.2 to reflect changes to stylesheet options. + - Factored ``SettingsSpec`` out of ``Component``; separately useful. + - Bumped version to 0.2.3 because of the new "--embed-stylesheet" + option and its effect on the PEP template & writer. + - Bumped version to 0.2.4 due to changes to the PEP template & + stylesheet. + - Bumped version to 0.2.5 to reflect changes to Reporter output. + - Added ``TransformSpec`` class for new transform system. + - Bumped version to 0.2.6 for API changes (renaming). + - Bumped version to 0.2.7 for new ``docutils.core.publish_*`` + convenience functions. + - Added ``Component.component_type`` attribute. + - Bumped version to 0.2.8 because of the internal parser switch from + plain lists to the docutils.statemachine.StringList objects. + - Bumped version to 0.2.9 because of the frontend.py API changes. + - Bumped version to 0.2.10 due to changes to the project layout + (third-party modules removed from the "docutils" package), and + signature changes in ``io.Input``/``io.Output``. + - Changed version to 0.3.0 for release. + +* docutils/core.py: + + - Made ``publish()`` a bit more convenient. + - Generalized ``Publisher.set_io``. + - Renamed ``publish()`` to ``publish_cmdline()``; rearranged its + parameters; improved its docstring. + - Added ``publish_file()`` and ``publish_string()``. + - Factored ``Publisher.set_source()`` and ``.set_destination()`` + out of ``.set_io``. + - Added support for "--dump-pseudo-xml", "--dump-settings", and + "--dump-transforms" hidden options. + - Added ``Publisher.apply_transforms()`` method. + - Added ``Publisher.set_components()`` method; support for + ``publish_*()`` conveninece functions. + - Moved config file processing to docutils/frontend.py. + - Added support for exit status ("exit_level" setting & + ``enable_exit`` parameter for Publisher.publish() and convenience + functions). + +* docutils/frontend.py: + + - Check for & exit on identical source & destination paths. + - Fixed bug with absolute paths & "--config". + - Set non-command-line defaults in ``OptionParser.__init__()``: + ``_source`` & ``_destination``. + - Distributed ``relative_path_settings`` to components; updated + ``OptionParser.populate_from_components()`` to combine it all. + - Require list of keys in ``make_paths_absolute`` (was implicit in + global ``relative_path_settings``). + - Added "--expose-internal-attribute", "--dump-pseudo-xml", + "--dump-settings", and "--dump-transforms" hidden options. + - Removed nasty internals-fiddling ``ConfigParser.get_section`` + code, replaced with correct code. + - Added validation functionality for config files. + - Added "--error-encoding" option/setting, "_disable_config" + internal setting. + - Added encoding validation; updated "--input-encoding" and + "--output-encoding"; added "--error-encoding-error-handler" and + "--output-encoding-error-handler". + - Moved config file processing from docutils/core.py. + - Updated ``OptionParser.populate_from_components`` to handle new + ``SettingsSpec.settings_defaults`` dict. + - Added support for "-" => stdin/stdout. + - Added "exit_level" setting ("--exit" option). + +* docutils/io.py: + + - Split ``IO`` classes into subclasses of ``Input`` and ``Output``. + - Added automatic closing to ``FileInput`` and ``FileOutput``. + - Delayed opening of ``FileOutput`` file until ``write()`` called. + - ``FileOutput.write()`` now returns the encoded output string. + - Try to get path/stream name automatically in ``FileInput`` & + ``FileOutput``. + - Added defaults for source & destination paths. + - Allow for Unicode I/O with an explicit "unicode" encoding. + - Added ``Output.encode()``. + - Removed dependency on runtime settings; pass encoding directly. + - Recognize Unicode strings in ``Input.decode()``. + - Added support for output encoding error handlers. + +* docutils/nodes.py: + + - Added "Invisible" element category class. + - Changed ``Node.walk()`` & ``.walkabout()`` to permit more tree + modification during a traversal. + - Added element classes: ``line_block``, ``generated``, ``address``, + ``sidebar``, ``rubric``, ``attribution``, ``admonition``, + ``superscript``, ``subscript``, ``inline`` + - Added support for lists of nodes to ``Element.insert()``. + - Fixed parent linking in ``Element.replace()``. + - Added new abstract superclass ``FixedTextElement``; adds + "xml:space" attribute. + - Added support for "line" attribute of ``system_message`` nodes. + - Added support for the observer pattern from ``utils.Reporter``. + Added ``parse_messages`` and ``transform_messages`` attributes to + ``document``, removed ``messages``. Added ``note_parse_message`` + and ``note_transform_message`` methods. + - Added support for improved diagnostics: + + - Added "document", "source", and "line" internal attributes to + ``Node``, set by ``Node.setup_child()``. + - Converted variations on ``node.parent = self`` to + ``self.setup_child(node)``. + - Added ``document.current_source`` & ``.current_line`` + attributes, and ``.note_source`` observer method. + - Changed "system_message" output to GNU-Tools format. + + - Added a "rawsource" attribute to the ``Text`` class, for text + before backslash-escape resolution. + - Support for new transform system. + - Reworked ``pending`` element. + - Fixed XML DOM bug (SF #660611). + - Removed the ``interpeted`` element class and added + ``title_reference``, ``abbreviation``, ``acronym``. + - Made substitutions case-sensitive-but-forgiving; moved some code + from the parser. + - Fixed Unicode bug on element attributes (report: William Dode). + +* docutils/optik.py: Removed from project; replaced with + extras/optparse.py and extras/textwrap.py. These will be installed + only if they're not already present in the Python installation. + +* docutils/roman.py: Moved to extras/roman.py; this will be installed + only if it's not already present in the Python installation. + +* docutils/statemachine.py: + + - Factored out ``State.add_initial_transitions()`` so it can be + extended. + - Converted whitespace-specific "blank" and "indent" transitions + from special-case code to ordinary transitions: removed + ``StateMachineWS.check_line()`` & ``.check_whitespace()``, added + ``StateWS.add_initial_transitions()`` method, ``ws_patterns`` & + ``ws_initial_transitions`` attributes. + - Removed ``State.match_transition()`` after merging it into + ``.check_line()``. + - Added ``StateCorrection`` exception. + - Added support for ``StateCorrection`` in ``StateMachine.run()`` + (moved ``TransitionCorrection`` support there too.) + - Changed ``StateMachine.next_line()`` and ``.goto_line()`` to raise + ``EOFError`` instead of ``IndexError``. + - Added ``State.no_match`` method. + - Added support for the Observer pattern, triggered by input line + changes. + - Added ``strip_top`` parameter to + ``StateMachineWS.get_first_known_indented``. + - Made ``context`` a parameter to ``StateMachine.run()``. + - Added ``ViewList`` & ``StringList`` classes; + ``extract_indented()`` becomes ``StringList.get_indented()``. + - Added ``StateMachine.insert_input()``. + - Fixed ViewList slice handling for Python 2.3. Patch from (and + thanks to) Fred Drake. + +* docutils/utils.py: + + - Added a ``source`` attribute to Reporter instances and + ``system_message`` elements. + - Added an observer pattern to ``utils.Reporter`` to keep track of + system messages. + - Fixed bugs in ``relative_path()``. + - Added support for improved diagnostics. + - Moved ``normalize_name()`` to nodes.py (``fully_normalize_name``). + - Added support for encoding Reporter stderr output, and encoding + error handlers. + - Reporter keeps track of the highest level system message yet + generated. + +* docutils/languages: Fixed bibliographic field language lookups. + +* docutils/languages/es.py: Added to project; Spanish mappings by + Marcelo Huerta San Martin. + +* docutils/languages/fr.py: Added to project; French mappings by + Stefane Fermigier. + +* docutils/languages/it.py: Added to project; Italian mappings by + Nicola Larosa. + +* docutils/languages/sk.py: Added to project; Slovak mappings by + Miroslav Vasko. + +* docutils/parser/__init__.py: + + - Added ``Parser.finish_parse()`` method. + +* docutils/parser/rst/__init__.py: + + - Added options: "--pep-references", "--rfc-references", + "--tab-width", "--trim-footnote-reference-space". + +* docutils/parsers/rst/states.py: + + - Changed "title under/overline too short" system messages from INFO + to WARNING, and fixed its insertion location. + - Fixed enumerated list item parsing to allow paragraphs & section + titles to begin with enumerators. + - Converted system messages to use the new "line" attribute. + - Fixed a substitution reference edge case. + - Added support for "--pep-references" and "--rfc-references" + options; reworked ``Inliner`` code to make customization easier. + - Removed field argument parsing. + - Added support for short section title over/underlines. + - Fixed "simple reference name" regexp to ignore text like + "object.__method__"; not an anonymous reference. + - Added support for improved diagnostics. + - Reworked directive API, based on Dethe Elza's contribution. Added + ``Body.parse_directive()``, ``.parse_directive_options()``, + ``.parse_directive_arguments()`` methods. + - Added ``ExtensionOptions`` class, to parse directive options + without parsing field bodies. Factored + ``Body.parse_field_body()`` out of ``Body.field()``, overridden in + ``ExtensionOptions``. + - Improved definition list term/classifier parsing. + - Added warnings for unknown directives. + - Renamed ``Stuff`` to ``Struct``. + - Now flagged as errors: transitions at the beginning or end of + sections, empty sections (except title), and empty documents. + - Updated for ``statemachine.StringList``. + - Enabled recognition of schemeless email addresses in targets. + - Added support for embedded URIs in hyperlink references. + - Added backslash-escapes to inline markup end-string suffix. + - Added support for correct interpreted text processing. + - Fixed nested title parsing (topic, sidebar directives). + - Added special processing of backslash-escaped whitespace (idea + from David Abrahams). + - Made substitutions case-sensitive-but-forgiving; moved some code + to ``docutils.nodes``. + - Added support for block quote attributions. + - Added a kludge to work-around a conflict between the bubble-up + parser strategy and short titles (<= 3 char-long over- & + underlines). Fixes SF bug #738803 "infinite loop with multiple + titles" submitted by Jason Diamond. + - Added explicit interpreted text roles for standard inline markup: + "emphasis", "strong", "literal". + - Implemented "superscript" and "subscript" interpreted text roles. + - Added initial support for "abbreviation" and "acronym" roles; + incomplete. + - Added support for "--trim-footnote-reference-space" option. + - Optional space before colons in directives & hyperlink targets. + +* docutils/parsers/rst/tableparser.py: + + - Fixed a bug that was producing unwanted empty rows in "simple" + tables. + - Detect bad column spans in "simple" tables. + +* docutils/parsers/rst/directives: Updated all directive functions to + new API. + +* docutils/parsers/rst/directives/__init__.py: + + - Added ``flag()``, ``unchanged()``, ``path()``, + ``nonnegative_int()``, ``choice()``, and ``class_option()`` + directive option helper functions. + - Added warnings for unknown directives. + - Return ``None`` for missing directives. + - Added ``register_directive()``, thanks to William Dode and Paul + Moore. + +* docutils/parsers/rst/directives/admonitions.py: + + - Added "admonition" directive. + +* docutils/parsers/rst/directives/body.py: Added to project. Contains + the "topic", "sidebar" (from Patrick O'Brien), "line-block", + "parsed-literal", "rubric", "epigraph", "highlights" and + "pull-quote" directives. + +* docutils/parsers/rst/directives/images.py: + + - Added an "align" attribute to the "image" & "figure" directives + (by Adam Chodorowski). + - Added "class" option to "image", and "figclass" to "figure". + +* docutils/parsers/rst/directives/misc.py: + + - Added "include", "raw", and "replace" directives, courtesy of + Dethe Elza. + - Added "unicode" and "class" directives. + +* docutils/parsers/rst/directives/parts.py: + + - Added the "sectnum" directive; by Dmitry Jemerov. + - Added "class" option to "contents" directive. + +* docutils/parsers/rst/directives/references.py: Added to project. + Contains the "target-notes" directive. + +* docutils/parsers/rst/languages/__init__.py: + + - Return ``None`` from get_language() for missing language modules. + +* docutils/parsers/rst/languages/de.py: Added to project; German + mappings by Engelbert Gruber. + +* docutils/parsers/rst/languages/en.py: + + - Added interpreted text roles mapping. + +* docutils/parsers/rst/languages/es.py: Added to project; Spanish + mappings by Marcelo Huerta San Martin. + +* docutils/parsers/rst/languages/fr.py: Added to project; French + mappings by William Dode. + +* docutils/parsers/rst/languages/it.py: Added to project; Italian + mappings by Nicola Larosa. + +* docutils/parsers/rst/languages/sk.py: Added to project; Slovak + mappings by Miroslav Vasko. + +* docutils/readers/__init__.py: + + - Added support for the observer pattern from ``utils.Reporter``, in + ``Reader.parse`` and ``Reader.transform``. + - Removed ``Reader.transform()`` method. + - Added default parameter values to ``Reader.__init__()`` to make + instantiation easier. + - Removed bogus aliases: "restructuredtext" is *not* a Reader. + +* docutils/readers/pep.py: + + - Added the ``peps.TargetNotes`` transform to the Reader. + - Removed PEP & RFC reference detection code; moved to + parsers/rst/states.py as options (enabled here by default). + - Added support for pre-acceptance PEPs (no PEP number yet). + - Moved ``Inliner`` & made it a class attribute of ``Reader`` for + easy subclassing. + +* docutils/readers/python: Python Source Reader subpackage added to + project, including preliminary versions of: + + - __init__.py + - moduleparser.py: Parser for Python modules. + +* docutils/transforms/__init__.py: + + - Added ``Transformer`` class and completed transform reform. + - Added unknown_reference_resolvers list for each transformer. This list holds + the list of functions provided by each component of the transformer that + help resolve references. + +* docutils/transforms/frontmatter.py: + + - Improved support for generic fields. + - Fixed bibliographic field language lookups. + +* docutils/transforms/misc.py: Added to project. Miscellaneous + transforms. + +* docutils/transforms/parts.py: + + - Moved the "id" attribute from TOC list items to the references + (``Contents.build_contents()``). + - Added the ``SectNum`` transform; by Dmitry Jemerov. + - Added "class" attribute support to ``Contents``. + +* docutils/transforms/peps.py: + + - Added ``mask_email()`` function, updating to pep2html.py's + functionality. + - Linked "Content-Type: text/x-rst" to PEP 12. + - Added the ``TargetNotes`` PEP-specific transform. + - Added ``TargetNotes.cleanup_callback``. + - Added title check to ``Headers``. + +* docutils/transforms/references.py: + + - Added the ``TargetNotes`` generic transform. + - Split ``Hyperlinks`` into multiple transforms. + - Fixed bug with multiply-indirect references (report: Bruce Smith). + - Added check for circular indirect references. + - Made substitutions case-sensitive-but-forgiving. + +* docutils/transforms/universal.py: + + - Added support for the "--expose-internal-attributes" option. + - Removed ``Pending`` transform classes & data. + +* docutils/writers/__init__.py: + + - Removed ``Writer.transform()`` method. + +* docutils/writers/docutils-xml.py: + + - Added XML and doctype declarations. + - Added "--no-doctype" and "--no-xml-declaration" options. + +* docutils/writers/html4css1.py: + + - "name" attributes only on these tags: a, applet, form, frame, + iframe, img, map. + - Added "name" attribute to <a> in section titles for Netscape 4 + support (bug report: Pearu Peterson). + - Fixed targets (names) on footnote, citation, topic title, + problematic, and system_message nodes (for Netscape 4). + - Changed field names from "<td>" to "<th>". + - Added "@" to "@" encoding to thwart address harvesters. + - Improved the vertical whitespace optimization; ignore "invisible" + nodes (targets, comments, etc.). + - Improved inline literals with ``<span class="pre">`` around chunks + of text and `` `` for runs of spaces. + - Improved modularity of output; added ``self.body_pre_docinfo`` and + ``self.docinfo`` segments. + - Added support for "line_block", "address" elements. + - Improved backlinks (footnotes & system_messages). + - Improved system_message output. + - Redefined "--stylesheet" as containing an invariant URL, used + verbatim. Added "--stylesheet-path", interpreted w.r.t. the + working directory. + - Added "--footnote-references" option (superscript or brackets). + - Added "--compact-lists" and "--no-compact-lists" options. + - Added "--embed-stylesheet" and "--link-stylesheet" options; + factored out ``HTMLTranslator.get_stylesheet_reference()``. + - Improved field list rendering. + - Added Docutils version to "generator" meta tag. + - Fixed a bug with images; they must be inline, so wrapped in <p>. + - Improved layout of <pre> HTML source. + - Fixed attribute typo on <colspec>. + - Refined XML prologue. + - Support for no stylesheet. + - Removed "interpreted" element support. + - Added support for "title_reference", "sidebar", "attribution", + "rubric", and generic "admonition" elements. + - Added "--attribution" option. + - Added support for "inline", "subscript", "superscript" elements. + - Added initial support for "abbreviation" and "acronym"; + incomplete. + +* docutils/writers/latex2e.py: LaTeX Writer, added by Engelbert Gruber + (from the sandbox). + + - Added french. + - Double quotes in literal blocks (special treatment for de/ngerman). + - Added '--hyperlink-color' option ('0' turns off coloring of links). + - Added "--attribution" option. + - Right align attributions. + +* docutils/writers/pep_html.py: + + - Parameterized output encoding in PEP template. + - Reworked substitutions from ``locals()`` into ``subs`` dict. + - Redefined "--pep-stylesheet" as containing an invariant URL, used + verbatim. Added "--pep-stylesheet-path", interpreted w.r.t. the + working directory. + - Added an override on the "--footnote-references" option. + - Factored out ``HTMLTranslator.get_stylesheet_reference()``. + - Added Docutils version to "generator" meta tag. + - Added a "DO NOT EDIT THIS FILE" comment to generated HTML. + +* docs/tools.txt: + + - Added a "silent" setting for ``buildhtml.py``. + - Added a "Getting Help" section. + - Rearranged the structure. + - Kept up to date, with new settings, command-line options etc. + - Added section for ``rst2latex.py`` (Engelbert Gruber). + - Converted settings table into a definition list. + +* docs/rst/quickstart.txt: + + - Added a table of contents. + - Added feedback information. + - Added mention of minimum section title underline lengths. + - Removed the 4-character minimum for section title underlines. + +* docs/rst/quickref.html: + + - Added a "Getting Help" section. + - Added a style to make section title backlinks more subtle. + - Added mention of minimum section title underline lengths. + - Removed the 4-character minimum for section title underlines. + +* extras: Directory added to project; contains third-party modules + that Docutils depends on (optparse, textwrap, roman). These are + only installed if they're not already present. + +* licenses: Directory added to project; contains copies of license + files for non-public-domain files. + +* spec/doctree.txt: + + - Changed the focus. It's about DTD elements: structural + relationships, semantics, and external (public) attributes. Not + about the element class library. + - Moved some implementation-specific stuff into ``docutils.nodes`` + docstrings. + - Wrote descriptions of all common attributes and parameter + entities. Filled in introductory material. + - Working through the element descriptions: 55 down, 37 to go. + - Removed "Representation of Horizontal Rules" to + spec/rst/alternatives.txt. + +* spec/docutils.dtd: + + - Added "generated" inline element. + - Added "line_block" body element. + - Added "auto" attribute to "title". + - Changed content models of "literal_block" and "doctest_block" to + ``%text.model``. + - Added ``%number;`` attribute type parameter entity. + - Changed ``%structural.elements;`` to ``%section.elements``. + - Updated attribute types; made more specific. + - Added "address" bibliographic element. + - Added "line" attribute to ``system_message`` element. + - Removed "field_argument" element; "field_name" may contain + multiple words and whitespace. + - Changed public identifier to docutils.sf.net. + - Removed "interpreted" element; added "title_reference", + "abbreviation", "acronym". + - Removed "refuri" attribute from "footnote_reference" and + "citation_reference". + - Added "sidebar", "rubric", "attribution", "admonition", + "superscript", "subscript", and "inline" elements. + +* spec/pep-0256.txt: Converted to reStructuredText & updated. + +* spec/pep-0257.txt: Converted to reStructuredText & updated. + +* spec/pep-0258.txt: Converted to reStructuredText & updated. + +* spec/semantics.txt: Updated with text from a Doc-SIG response to + Dallas Mahrt. + +* spec/transforms.txt: Added to project. + +* spec/howto: Added subdirectory, for developer how-to docs. + +* spec/howto/rst-directives.txt: Added to project. Original by Dethe + Elza, edited & extended by David Goodger. + +* spec/howto/i18n.txt: Docutils Internationalization. Added to + project. + +* spec/rst/alternatives.txt: + + - Added "Doctree Representation of Transitions" from + spec/doctree.txt. + - Updated "Inline External Targets" & closed the debate. + - Added ideas for interpreted text syntax extensions. + - Added "Nested Inline Markup" section. + +* spec/rst/directives.txt: + + - Added directives: "topic", "sectnum", "target-notes", + "line-block", "parsed-literal", "include", "replace", "sidebar", + "admonition", "rubric", "epigraph", "highlights", "unicode" and + "class". + - Formalized descriptions of directive details. + - Added an "align" attribute to the "image" & "figure" directives + (by Adam Chodorowski). + - Added "class" options to "topic", "sidebar", "line-block", + "parsed-literal", "contents", and "image"; and "figclass" to + "figure". + +* spec/rst/interpreted.txt: Added to project. Descriptions of + interpreted text roles. + +* spec/rst/introduction.txt: + + - Added pointers to material for new users. + +* spec/rst/reStructuredText.txt: + + - Disambiguated comments (just add a newline after the "::"). + - Updated enumerated list description; added a discussion of the + second-line validity checking. + - Updated directive description. + - Added a note redirecting newbies to the user docs. + - Expanded description of inline markup start-strings in non-markup + contexts. + - Removed field arguments and made field lists a generic construct. + - Removed the 4-character minimum for section title underlines. + - Clarified term/classifier delimiter & inline markup ambiguity + (definition lists). + - Added "Embedded URIs". + - Updated "Interpreted Text" section. + - Added "Character-Level Inline Markup" section. + +* test: Continually adding & updating tests. + + - Moved test/test_rst/ to test/test_parsers/test_rst/. + - Moved test/test_pep/ to test/test_readers/test_pep/. + - Added test/test_readers/test_python/. + - Added test/test_writers/ (Engelbert Gruber). + +* tools: + + - Made the ``locale.setlocale()`` calls in front ends + fault-tolerant. + +* tools/buildhtml.py: + + - Added "--silent" option. + - Fixed bug with absolute paths & "--config". + - Updated for new I/O classes. + - Added some exception handling. + - Separated publishers' setting defaults; prevents interference. + - Updated for new ``publish_file()`` convenience function. + +* tools/pep-html-template: + + - Allow for "--embed-stylesheet". + - Added Docutils version to "generator" meta tag. + - Added a "DO NOT EDIT THIS FILE" comment to generated HTML. + - Conform to XHTML spec. + +* tools/pep2html.py: + + - Made ``argv`` a parameter to ``main()``. + - Added support for "Content-Type:" header & arbitrary PEP formats. + - Linked "Content-Type: text/plain" to PEP 9. + - Files skipped (due to an error) are not pushed onto the server. + - Updated for new I/O classes. + - Added ``check_requirements()`` & ``pep_type_error()``. + - Added some exception handling. + - Updated for new ``publish_string()`` convenience function. + - Added a "DO NOT EDIT THIS FILE" comment to generated HTML. + +* tools/quicktest.py: + + - Added "-V"/"--version" option. + +* tools/rst2latex.py: LaTeX front end, added by Engelbert Gruber. + +* tools/unicode2rstsubs.py: Added to project. Produces character + entity files (reSructuredText substitutions) from the MathML master + unicode.xml file. + +* tools/editors: Support code for editors, added to project. Contains + ``emacs/restructuredtext.el``. + +* tools/stylesheets/default.css: Moved into the stylesheets directory. + + - Added style for chunks of inline literals. + - Removed margin for first child of table cells. + - Right-aligned field list names. + - Support for auto-numbered section titles in TOCs. + - Increased the size of inline literals (<tt>) in titles. + - Restored the light gray background for inline literals. + - Added support for "line_block" elements. + - Added style for "address" elements. + - Removed "a.footnote-reference" style; doing it with ``<sup>`` now. + - Improved field list rendering. + - Vertical whitespace improvements. + - Removed "a.target" style. + +* tools/stylesheets/pep.css: + + - Fixed nested section margins. + - Other changes parallel those of ``../default.css``. + + +Release 0.2 (2002-07-31) +======================== + +General: + +- The word "component" was being used ambiguously. From now on, + "component" will be used to mean "Docutils component", as in Reader, + Writer, Parser, or Transform. Portions of documents (Table of + Contents, sections, etc.) will be called "document parts". +- Did a grand renaming: a lot of ``verylongnames`` became + ``very_long_names``. +- Cleaned up imports: no more relative package imports or + comma-separated lists of top-level modules. +- Added support for an option values object which carries default + settings and overrides (from command-line options and library use). +- Added internal Unicode support, and support for both input and + output encodings. +- Added support for the ``docutils.io.IO`` class & subclasses. + +Specific: + +* docutils/__init__.py: + + - Added ``ApplicationError`` and ``DataError``, for use throughout + the package. + - Added ``Component`` base class for Docutils components; implements + the ``supports`` method. + - Added ``__version__`` (thus, ``docutils.__version__``). + +* docutils/core.py: + + - Removed many keyword parameters to ``Publisher.__init__()`` and + ``publish()``; bundled into an option values object. Added + "argv", "usage", "description", and "option_spec" parameters for + command-line support. + - Added ``Publisher.process_command_line()`` and ``.set_options()`` + methods. + - Reworked I/O model for ``docutils.io`` wrappers. + - Updated ``Publisher.set_options()``; now returns option values + object. + - Added support for configuration files (/etc/docutils.conf, + ./docutils.conf, ~/.docutils). + - Added ``Publisher.setup_option_parser()``. + - Added default usage message and description. + +* docutils/frontend.py: Added to project; support for front-end + (command-line) scripts. Option specifications may be augmented by + components. Requires Optik (http://optik.sf.net/) for option + processing (installed locally as docutils/optik.py). + +* docutils/io.py: Added to project; uniform API for a variety of input + output mechanisms. + +* docutils/nodes.py: + + - Added ``TreeCopyVisitor`` class. + - Added a ``copy`` method to ``Node`` and subclasses. + - Added a ``SkipDeparture`` exception for visitors. + - Renamed ``TreePruningException`` from ``VisitorException``. + - Added docstrings to ``TreePruningException``, subclasses, and + ``Nodes.walk()``. + - Improved docstrings. + - Added ``SparseNodeVisitor``, refined ``NodeVisitor``. + - Moved ``utils.id()`` to ``nodes.make_id()`` to avoid circular + imports. + - Added ``decoration``, ``header``, and ``footer`` node classes, and + ``PreDecorative`` mixin. + - Reworked the name/id bookkeeping; to ``document``, removed + ``explicit_targets`` and ``implicit_targets`` attributes, added + ``nametypes`` attribute and ``set_name_id_map`` method. + - Added ``NodeFound`` exception, for use with ``NodeVisitor`` + traversals. + - Added ``document.has_name()`` method. + - Fixed DOM generation for list-attributes. + - Added category class ``Labeled`` (used by footnotes & citations). + - Added ``Element.set_class()`` method (sets "class" attribute). + +* docutils/optik.py: Added to project. Combined from the Optik + package, with added option groups and other modifications. The use + of this module is probably only temporary. + +* docutils/statemachine.py: + + - Added ``runtime_init`` method to ``StateMachine`` and ``State``. + - Added underscores to improve many awkward names. + - In ``string2lines()``, changed whitespace normalizing translation + table to regexp; restores Python 2.0 compatibility with Unicode. + +* docutils/urischemes.py: + + - Filled in some descriptions. + - Added "shttp" scheme. + +* docutils/utils.py: + + - Added ``clean_rcs_keywords`` function (moved from + docutils/transforms/frontmatter.py + ``DocInfo.filter_rcs_keywords``). + - Added underscores to improve many awkward names. + - Changed names of Reporter's thresholds: + warning_level -> report_level; error_level -> halt_level. + - Moved ``utils.id()`` to ``nodes.make_id()``. + - Added ``relative_path(source, target)``. + +* docutils/languages/de.py: German mappings; added to project. Thanks + to Gunnar Schwant for the translations. + +* docutils/languages/en.py: Added "Dedication" bibliographic field + mappings. + +* docutils/languages/sv.py: Swedish mappings; added to project by Adam + Chodorowski. + +* docutils/parsers/rst/states.py: + + - Added underscores to improve many awkward names. + - Added RFC-2822 header support. + - Extracted the inline parsing code from ``RSTState`` to a separate + class, ``Inliner``, which will allow easy subclassing. + - Made local bindings for ``memo`` container & often-used contents + (reduces code complexity a lot). See ``RSTState.runtime_init()``. + - ``RSTState.parent`` replaces ``RSTState.statemachine.node``. + - Added ``MarkupMismatch`` exception; for late corrections. + - Added ``-/:`` characters to inline markup's start string prefix, + ``/`` to end string suffix. + - Fixed a footnote bug. + - Fixed a bug with literal blocks. + - Applied patch from Simon Budig: simplified regexps with symbolic + names, removed ``Inliner.groups`` and ``Body.explicit.groups``. + - Converted regexps from ``'%s' % var`` to ``'%(var)s' % locals()``. + - Fixed a bug in ``Inliner.interpreted_or_phrase_ref()``. + - Allowed non-ASCII in "simple names" (directive names, field names, + references, etc.). + - Converted ``Inliner.patterns.initial`` to be dynamically built + from parts with ``build_regexp()`` function. + - Changed ``Inliner.inline_target`` to ``.inline_internal_target``. + - Updated docstrings. + - Changed "table" to "grid_table"; added "simple_table" support. + +* docutils/parsers/rst/tableparser.py: + + - Changed ``TableParser`` to ``GridTableParser``. + - Added ``SimpleTableParser``. + - Refactored naming. + +* docutils/parsers/rst/directives/__init__.py: Added "en" (English) as + a fallback language for directive names. + +* docutils/parsers/rst/directives/html.py: Changed the ``meta`` + directive to use a ``pending`` element, used only by HTML writers. + +* docutils/parsers/rst/directives/parts.py: Renamed from + components.py. + + - Added "backlinks" attribute to "contents" directive. + +* docutils/parsers/rst/languages/sv.py: Swedish mappings; added to + project by Adam Chodorowski. + +* docutils/readers/__init__.py: Gave Readers more control over + choosing and instantiating Parsers. + +* docutils/readers/pep.py: Added to project; for PEP processing. + +* docutils/transforms/__init__.py: ``Transform.__init__()`` now + requires a ``component`` parameter. + +* docutils/transforms/components.py: Added to project; transforms + related to Docutils components. + +* docutils/transforms/frontmatter.py: + + - In ``DocInfo.extract_authors``, check for a single "author" in an + "authors" group, and convert it to a single "author" element. + - Added support for "Dedication" and generic bibliographic fields. + +* docutils/transforms/peps.py: Added to project; PEP-specific. + +* docutils/transforms/parts.py: Renamed from old components.py. + + - Added filter for `Contents`, to use alt-text for inline images, + and to remove inline markup that doesn't make sense in the ToC. + - Added "name" attribute to TOC topic depending on its title. + - Added support for optional TOC backlinks. + +* docutils/transforms/references.py: Fixed indirect target resolution + in ``Hyperlinks`` transform. + +* docutils/transforms/universal.py: + + - Changed ``Messages`` transform to properly filter out system + messages below the warning threshold. + - Added ``Decorations`` transform (support for ``--generator``, + ``--date``, ``--time``, ``--source-link`` options). + +* docutils/writers/__init__.py: Added "pdf" alias in anticipation of + Engelbert Gruber's PDF writer. + +* docutils/writers/html4css1.py: + + - Made XHTML-compatible (switched to lowercase element & attribute + names; empty tag format). + - Escape double-dashes in comment text. + - Improved boilerplate & modularity of output. + - Exposed modular output in Writer class. + - Added a "generator" meta tag to <head>. + - Added support for the ``--stylesheet`` option. + - Added support for ``decoration``, ``header``, and ``footer`` + elements. + - In ``HTMLTranslator.attval()``, changed whitespace normalizing + translation table to regexp; restores Python 2.0 compatibility + with Unicode. + - Added the translator class as instance variable to the Writer, to + make it easily subclassable. + - Improved option list spacing (thanks to Richard Jones). + - Modified field list output. + - Added backlinks to footnotes & citations. + - Added percentage widths to "<col>" tags (from colspec). + - Option lists: "<code>" changed to "<kbd>", ``option_argument`` + "<span>" changed to "<var>". + - Inline literals: "<code>" changed to "<tt>". + - Many changes to optimize vertical space: compact simple lists etc. + - Add a command-line options & directive attributes to control TOC + and footnote/citation backlinks. + - Added support for optional footnote/citation backlinks. + - Added support for generic bibliographic fields. + - Identify backrefs. + - Relative URLs for stylesheet links. + +* docutils/writers/pep_html.py: Added to project; HTML Writer for + PEPs (subclass of ``html4css1.Writer``). + +* docutils/writers/pseudoxml.py: Renamed from pprint.py. + +* docutils/writers/docutils_xml.py: Added to project; trivial writer + of the Docutils internal doctree in XML. + +* docs/tools.txt: "Docutils Front-End Tools", added to project. + +* spec/doctree.txt: + + - Changed the title to "The Docutils Document Tree". + - Added "Hyperlink Bookkeeping" section. + +* spec/docutils.dtd: + + - Added ``decoration``, ``header``, and ``footer`` elements. + - Brought ``interpreted`` element in line with the parser: changed + attribute "type" to "role", added "position". + - Added support for generic bibliographic fields. + +* spec/notes.txt: Continual updates. Added "Project Policies". + +* spec/pep-0256.txt: Updated. Added "Roadmap to the Doctring PEPs" + section. + +* spec/pep-0257.txt: Clarified prohibition of signature repetition. + +* spec/pep-0258.txt: Updated. Added text from pysource.txt and + mailing list discussions. + +* spec/pep-0287.txt: + + - Renamed to "reStructuredText Docstring Format". + - Minor edits. + - Reworked Q&A as an enumerated list. + - Converted to reStructuredText format. + +* spec/pysource.dtd: + + - Reworked structural elements, incorporating ideas from Tony Ibbs. + +* spec/pysource.txt: Removed from project. Moved much of its contents + to pep-0258.txt. + +* spec/rst/alternatives.txt: + + - Expanded auto-enumerated list idea; thanks to Fred Bremmer. + - Added "Inline External Targets" section. + +* spec/rst/directives.txt: + + - Added "backlinks" attribute to "contents" directive. + +* spec/rst/problems.txt: + + - Updated the Enumerated List Markup discussion. + - Added new alternative table markup syntaxes. + +* spec/rst/reStructuredText.txt: + + - Clarified field list usage. + - Updated enumerated list description. + - Clarified purpose of directives. + - Added ``-/:`` characters to inline markup's start string prefix, + ``/`` to end string suffix. + - Updated "Authors" bibliographic field behavior. + - Changed "inline hyperlink targets" to "inline internal targets". + - Added "simple table" syntax to supplement the existing but + newly-renamed "grid tables". + - Added cautions for anonymous hyperlink use. + - Added "Dedication" and generic bibliographic fields. + +* test: Made test modules standalone (subdirectories became packages). + +* test/DocutilsTestSupport.py: + + - Added support for PEP extensions to reStructuredText. + - Added support for simple tables. + - Refactored naming. + +* test/package_unittest.py: Renamed from UnitTestFolder.py. + + - Now supports true packages containing test modules + (``__init__.py`` files required); fixes duplicate module name bug. + +* test/test_pep/: Subpackage added to project; PEP testing. + +* test/test_rst/test_SimpleTableParser.py: Added to project. + +* tools: + + - Updated html.py and publish.py front-end tools to use the new + command-line processing facilities of ``docutils.frontend`` + (exposed in ``docutils.core.Publisher``), reducing each to just a + few lines of code. + - Added ``locale.setlocale()`` calls to front-end tools. + +* tools/buildhtml.py: Added to project; batch-generates .html from all + the .txt files in directories and subdirectories. + +* tools/default.css: + + - Added support for ``header`` and ``footer`` elements. + - Added styles for "Dedication" topics (biblio fields). + +* tools/docutils.conf: A configuration file; added to project. + +* tools/docutils-xml.py: Added to project. + +* tools/pep.py: Added to project; PEP to HTML front-end tool. + +* tools/pep-html-template: Added to project. + +* tools/pep2html.py: Added to project from Python (nondist/peps). + Added support for Docutils (reStructuredText PEPs). + +* tools/quicktest.py: + + - Added the ``--attributes`` option, hacked a bit. + - Added a second command-line argument (output file); cleaned up. + +* tools/stylesheets/: Subdirectory added to project. + +* tools/stylesheets/pep.css: Added to project; stylesheet for PEPs. + + +Release 0.1 (2002-04-20) +======================== + +This is the first release of Docutils, merged from the now inactive +reStructuredText__ and `Docstring Processing System`__ projects. For +the pre-Docutils history, see the `reStructuredText HISTORY`__ and the +`DPS HISTORY`__ files. + +__ http://structuredtext.sourceforge.net/ +__ http://docstring.sourceforge.net/ +__ http://structuredtext.sourceforge.net/HISTORY.html +__ http://docstring.sourceforge.net/HISTORY.html + +General changes: renamed 'dps' package to 'docutils'; renamed +'restructuredtext' subpackage to 'rst'; merged the codebases; merged +the test suites (reStructuredText's test/test_states renamed to +test/test_rst); and all modifications required to make it all work. + +* docutils/parsers/rst/states.py: + + - Improved diagnostic system messages for missing blank lines. + - Fixed substitution_reference bug. + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..33ee605 --- /dev/null +++ b/README.txt @@ -0,0 +1,394 @@ +======================= + README: Docutils 0.14 +======================= + +:Author: David Goodger +:Contact: goodger@python.org +:Date: $Date: 2017-08-03 11:03:32 +0200 (Do, 03 Aug 2017) $ +:Web site: http://docutils.sourceforge.net/ +:Copyright: This document has been placed in the public domain. + +.. contents:: + + +Quick-Start +=========== + +This is for those who want to get up & running quickly. + +1. Docutils requires Python (version 2.4 or later), available from + + http://www.python.org/ + + See Requirements_ below for details. + +2. Use the latest Docutils code. Get the code from the `Subversion + repository`_ or from the snapshot: + + http://docutils.svn.sourceforge.net/viewvc/docutils/trunk/docutils/?view=tar + + See `Releases & Snapshots`_ below for details. + +3. Unpack the tarball in a temporary directory (**not** directly in + Python's ``site-packages``), go to the directory created by expanding + the archive, and run ``setup.py install``. On + Windows systems it may be sufficient to double-click ``install.py``. + + See Installation_ below for details. + +4. Use the front-end scripts to convert reStructuredText documents. + Try for example:: + + rst2html.py FAQ.txt FAQ.html (Unix) + python tools/rst2html.py FAQ.txt FAQ.html (Windows) + + See Usage_ below for details. + + +Purpose +======= + +The purpose of the Docutils project is to create a set of tools for +processing plaintext documentation into useful formats, such as HTML, +XML, and LaTeX. Support for the following sources has been +implemented: + +* Standalone files. + +* `PEPs (Python Enhancement Proposals)`_. + +Support for the following sources is planned: + +* Inline documentation from Python modules and packages, extracted + with namespace context. + +* Email (RFC-822 headers, quoted excerpts, signatures, MIME parts). + +* Wikis, with global reference lookups of "wiki links". + +* Compound documents, such as multiple chapter files merged into a + book. + +* And others as discovered. + +.. _PEPs (Python Enhancement Proposals): + http://www.python.org/peps/pep-0012.html + + +Releases & Snapshots +==================== + +While we are trying to follow a "release early & often" policy, +features are added frequently. Since the code in the Subversion +repository is usually in a bug-free state, we recommend that you use +a current snapshot. + +To get a snapshot, go to the code page and click the download snapshot +button: + +* Docutils code, documentation, front-end tools, and tests: + https://sourceforge.net/p/docutils/code/HEAD/tree/trunk/docutils/ + +* Sandbox (experimental, contributed code): + https://sourceforge.net/p/docutils/code/HEAD/tree/trunk/sandbox/ + +To keep up to date on the latest developments, download fresh copies of +the snapshots regularly or use a working copy of the +`Subversion repository`_. + +.. _Subversion repository: docs/dev/repository.html + + +Requirements +============ + +To run the code, Python_ must be installed. +Docutils is compatible with Python versions from 2.4 up to 2.7 and +versions 3.1 to 3.5 (cf. `Python 3 compatibility`_). + +Docutils uses the following packages for enhanced functionality, if they are +installed: + +* The `Python Imaging Library`_, or PIL, is used for some image + manipulation operations. + +* The `Pygments`_ syntax highlighter is used for content of `code` + directives and roles. + +.. _Python: http://www.python.org/. +.. _Python Imaging Library: http://www.pythonware.com/products/pil/ +.. _Pygments: http://pygments.org/ + + +Python 3 compatibility +---------------------- + +The Docutils codebase is written for Python 2 and uses "on-demand" +translation for `porting to Python 3`_. + +* The `setup.py` script generates Python 3 compatible sources in + ``build/`` and tests in ``tests3/`` sub-directories during + installation_ with Python 3. + +* The scripts in the ``tools/`` sub-directory work with all supported + Python versions without conversion. + +* To convert the sources without installing (e.g. for testing), run + ``python3 setup.py build``. + +* When editing the source, do changes on the Python 2 versions of the + files and re-run the build command. + +.. _porting to Python 3: http://docs.python.org/py3k/howto/pyporting.html + + +Project Files & Directories +=========================== + +* README.txt: You're reading it. + +* COPYING.txt: Public Domain Dedication and copyright details for + non-public-domain files (most are PD). + +* FAQ.txt: Frequently Asked Questions (with answers!). + +* RELEASE-NOTES.txt: Summary of the major changes in recent releases. + +* HISTORY.txt: A detailed change log, for the current and all previous + project releases. + +* BUGS.txt: Known bugs, and how to report a bug. + +* THANKS.txt: List of contributors. + +* setup.py: Installation script. See "Installation" below. + +* install.py: Quick & dirty installation script. Just run it. For + any kind of customization or help though, setup.py must be used. + +* docutils: The project source directory, installed as a Python + package. + +* docs: The project documentation directory. Read ``docs/index.txt`` + for an overview. + +* docs/user: The project user documentation directory. Contains the + following documents, among others: + + - docs/user/tools.txt: Docutils Front-End Tools + - docs/user/latex.txt: Docutils LaTeX Writer + - docs/user/rst/quickstart.txt: A ReStructuredText Primer + - docs/user/rst/quickref.html: Quick reStructuredText (HTML only) + +* docs/ref: The project reference directory. + ``docs/ref/rst/restructuredtext.txt`` is the reStructuredText + reference. + +* licenses: Directory containing copies of license files for + non-public-domain files. + +* tools: Directory for Docutils front-end tools. See + ``docs/user/tools.txt`` for documentation. + +* test: Unit tests. Not required to use the software, but very useful + if you're planning to modify it. See `Running the Test Suite`_ + below. + +Generated directories when installing under Python 3: + +* build: Converted sources. + +* test3: Converted tests. + + +Installation +============ + +The first step is to expand the ``.tgz`` archive in a temporary +directory (**not** directly in Python's ``site-packages``). It +contains a distutils setup file "setup.py". OS-specific installation +instructions follow. + + +GNU/Linux, BSDs, Unix, Mac OS X, etc. +------------------------------------- + +1. Open a shell. + +2. Go to the directory created by expanding the archive:: + + cd <archive_directory_path> + +3. Install the package (you may need root permissions to complete this + step):: + + su + (enter admin password) + python setup.py install + + If the python executable isn't on your path, you'll have to specify + the complete path, such as ``/usr/local/bin/python``. + + To install for a specific Python version, use this version in the + setup call, e.g. :: + + python3.1 setup.py install + + To install for different Python versions, repeat step 3 for every + required version. The last installed version will be used in the + `shebang line`_ of the ``rst2*.py`` wrapper scripts. + + .. _shebang line: http://en.wikipedia.org/wiki/Shebang_%28Unix%29 + +Windows +------- + +Just double-click ``install.py``. If this doesn't work, try the +following: + +1. Open a DOS Box (Command Shell, MS-DOS Prompt, or whatever they're + calling it these days). + +2. Go to the directory created by expanding the archive:: + + cd <archive_directory_path> + +3. Install the package:: + + <path_to_python.exe>\python setup.py install + + To install for a specific python version, specify the Python + executable for this version. + + To install for different Python versions, repeat step 3 for every + required version. + +Optional steps: + +* `running the test suite`_ + +* `converting the documentation`_ + + +Usage +===== + +There are many front-end tools in the unpacked "tools" subdirectory. +Installation under Unix places copies in the PATH. +You may want to begin with the "rst2html.py" front-end tool. Most +tools take up to two arguments, the source path and destination path, +with STDIN and STDOUT being the defaults. Use the "--help" option to +the front-end tools for details on options and arguments. See +Docutils Front-End Tools (``docs/user/tools.txt``) for full documentation. + +The package modules are continually growing and evolving. The +``docutils.statemachine`` module is usable independently. It contains +extensive inline documentation (in reStructuredText format of course). + +Contributions are welcome! + + +Converting the documentation +============================ + +After unpacking and installing the Docutils package, the following +shell commands will generate HTML for all included documentation:: + + cd <archive_directory_path>/tools + ./buildhtml.py ../ + +On Windows systems, type:: + + cd <archive_directory_path>\tools + python buildhtml.py .. + +The final directory name of the ``<archive_directory_path>`` is +"docutils" for snapshots. For official releases, the directory may be +called "docutils-X.Y.Z", where "X.Y.Z" is the release version. +Alternatively:: + + cd <archive_directory_path> + tools/buildhtml.py --config=tools/docutils.conf (Unix) + python tools\buildhtml.py --config=tools\docutils.conf (Windows) + +Some files may generate system messages (warnings and errors). The +``docs/user/rst/demo.txt`` file (under the archive directory) contains +five intentional errors. (They test the error reporting mechanism!) + + +Running the Test Suite +====================== + +The test suite is documented in `Docutils Testing`_ (docs/dev/testing.txt). + +To run the entire test suite, open a shell and use the following +commands:: + + cd <archive_directory_path>/test + ./alltests.py + +Under Windows, type:: + + cd <archive_directory_path>\test + python alltests.py + +For testing with Python 3 use the converted test suite:: + + cd <archive_directory_path>/test3 + python3 alltests.py + + +You should see a long line of periods, one for each test, and then a +summary like this:: + + Ran 1111 tests in 24.653s + + OK + Elapsed time: 26.189 seconds + +The number of tests will grow over time, and the times reported will +depend on the computer running the tests. The difference between the +two times represents the time required to set up the tests (import +modules, create data structures, etc.). + +If any of the tests fail, please `open a bug report`_ or `send an email`_ +(see `Bugs <BUGS.html>`_). +Please include all relevant output, information about your operating +system, Python version, and Docutils version. To see the Docutils +version, use one of the ``rst2*`` front ends or ``tools/quicktest.py`` +with the ``--version`` option, e.g.:: + + cd ../tools + ./quicktest.py --version + +Windows users type these commands:: + + cd ..\tools + python quicktest.py --version + + +.. _Docutils Testing: http://docutils.sourceforge.net/docs/dev/testing.html +.. _open a bug report: + http://sourceforge.net/p/docutils/bugs/ +.. _send an email: mailto:docutils-users@lists.sourceforge.net + ?subject=Test%20suite%20failure +.. _web interface: https://sourceforge.net/p/docutils/mailman/ + + +Getting Help +============ + +If you have questions or need assistance with Docutils or +reStructuredText, please post a message to the Docutils-users_ mailing +list. + +.. _Docutils-users: docs/user/mailing-lists.html#docutils-users + + +.. + Local Variables: + mode: indented-text + indent-tabs-mode: nil + sentence-end-double-space: t + fill-column: 70 + End: diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt new file mode 100644 index 0000000..c53568c --- /dev/null +++ b/RELEASE-NOTES.txt @@ -0,0 +1,665 @@ +.. -*- coding: utf-8 -*- + +======================== + Docutils Release Notes +======================== + +:Contact: grubert@users.sourceforge.net +:Maintainer: docutils-develop@lists.sourceforge.net +:Date: $Date: 2017-08-03 11:01:16 +0200 (Do, 03 Aug 2017) $ +:Revision: $Revision: 8147 $ +:Web site: http://docutils.sourceforge.net/ +:Copyright: This document has been placed in the public domain. + + +This document summarizes the major changes in recent and upcoming releases. +For a more detailed list of changes, please see the `Docutils History`_. + +.. _Docutils History: HISTORY.html + +.. contents:: + +Future changes +============== + +* Drop support for Python 2.4, 2.5, 3.1, and 3.2 immediately after the 0.14 + release. + +* Remove the `handle_io_errors` option from io.FileInput/Output. + Used by Sphinx up to version 1.3.1, fixed in 1.3.2 (Nov 29, 2015). + +* The default HTML writer "html" with frontend ``rst2html.py`` may change + from "html4css1" to "html5". + + Use `get_writer_by_name('html')` or the rst2html.py_ front end, if you + want the output to be up-to-date automatically. + + Use a specific writer name or front end, if you depend on stability of the + generated HTML code, e.g. because you use a custom style sheet or + post-processing that may break otherwise. + +.. _rst2html.py: docs/user/tools.html#rst2html-py + + +Release 0.14 (2017-08-03) +========================= + +As rc2. + +* docutils/docs/ref/docutils.dtd: + + - Enable validation of Docutils XML documents against the DTD: + +* docutils/parsers/rst/: + + - Added functionality: escaped whitespace in URI contexts. + - Consistent handling of all whitespace characters in inline markup + recognition. (May break documents that relied on some whitespace + characters (NBSP, ...) *not* to be recognized as whitespace.) + +* docutils/utils/smartquotes.py: + + - Update quote definitions for et, fi, fr, ro, sv, tr, uk. + - Add quote definitions for hr, hsb, hu, lv, sh, sl, sr. + - Differentiate apostrophe from closing single quote (if possible). + - Add command line interface for stand-alone use (requires 2.7). + +* docutils/writers/_html_base: + + - Provide default title in metadata. + - The MathJax CDN shut down on April 30, 2017. For security reasons, we + don't use a third party public installation as default but warn + if `math-output` is set to MathJax without specifying a URL. + See math-output_ for details. + +* docutils/writers/html4css1: + + - Respect automatic table column sizing. + +* docutils/writers/latex2e/__init__.py + + - Handle class arguments for block-level elements by wrapping them + in a "DUclass" environment. This replaces the special handling for + "epigraph" and "topic" elements. + +* docutils/writers/odf_odt: + + - Language option sets ODF document's default language + - Image width, scale, ... set image size in generated ODF. + +* tools/ + + - New front-end ``rst2html4.py``. + + +Release 0.13.1 (2016-12-09) +=========================== + +* docutils/writers/html5_polyglot + + - New HTML writer generating `HTML 5`_. + + .. _HTML 5: http://www.w3.org/TR/html5/ + +* tools/ + + - New front-end ``rst2html5.py``. + +* languages: persian/farsi (fa) and latvian (la) mappings. + +* change default base url for :rfc: to http://tools.ietf.org/html/ + +* tables accept widths, a list and align + +* latex2e: Fix admonition width, remove deprecated options, + better tablewidth auto, ... + +* rst.el: The problem with ``electric-indent-mode`` has been fixed. + + +Release 0.12 (2014-07-06) +========================= + +Small changes only, release current state + + +Release 0.11 (2013-07-22) +========================= + +* General + + - Apply [ 2714873 ] Fix for the overwritting of document attributes. + - Support embedded aliases within hyperlink references. + - Fix [ 228 ] try local import of docutils components (reader, writer, parser, + language module) before global search. + +* docutils/parsers/rst/directives/tables.py + + - Fix [ 210 ] Python 3.3 checks CVS syntax only if "strict" is True. + +* docutils/writers/html4css1/__init__.py + - Fix [ 3600051 ] for tables in a list, table cells are not compacted. + - New setting `stylesheet_dirs` (see above). + + Now, it is easy to add a custom stylesheet to Docutils' default + stylesheet with, e.g., ``--stylesheet_path='html4css1.css, mystyle.css'`` + + Changed behaviour of the default settings: + if there is a file ``html4css1.css`` in the working directory of the + process at launch, it is used instead of the one provided by Docutils + in the writer source directory. + + - New default for math-output_: ``HTML math.css``. + - Avoid repeated class declarations in html4css1 writer + (modified version of patch [ 104 ]). + +.. _math-output: docs/user/config.html#math-output + +* docutils/writers/latex2e/__init__.py + + - Drop the simple algorithm replacing straight double quotes with + English typographic ones. + Activate the SmartQuotes_ transform if you want this feature. + - New setting `stylesheet_dirs`: Comma-separated list of directories + where stylesheets are found. Used by `stylesheet_path` when expanding + relative path arguments. + +.. _SmartQuotes: docs/user/config.html#smart-quotes + +* docutils/writers/manpage.py + + - Fix [3607063] handle lines starting with a period. + - Fix option separating comma was bold (thanks to Bill Morris). + +Release 0.10 (2012-12-16) +========================= + +.. Note:: + + Docutils 0.9.x is the last version supporting Python 2.3. + + Docutils 0.10 is compatible with Python versions from 2.4 to 3.2 + (cf. `Python 3 compatibility`_). + +* General: + + - SmartQuotes transform for typographic quotes and dashes. + + - ``docutils/math``, ``docutils/error_reporting.py``, and + ``docutils/urischemes.py`` moved to the utils package. + Code importing these modules needs to adapt, e.g.:: + + try: + import docutils.math as math + except ImportError: + import docutils.utils.math as math + + - enhanced math and error handling. + +* docutils/io.py + + - FileInput/FileOutput: no system-exit on IOError. + The `handle_io_errors` option is ignored. + +.. _Python 3 compatibility: README.html#python-3-compatibility + +* docutils/writers/html4css1/__init__.py + + - Use ``<code>`` tag for inline "code", + do not drop nested inline nodes (syntax highlight tokens). + - Customizable MathJax URL (based on patch by Dmitry Shachnev). + - No line break after opening inline math tag. + +* docutils/writers/latex2e/__init__.py, docutils/writers/xetex/__init__.py + + - Fix section numbering by LaTeX. + +* docutils/writers/s5_html/__init__.py + + - Fix [ 3556388 ] Mathjax does not work with rst2s5. + + +Release 0.9.1 (2012-06-17) +========================== + +* General: + + Several fixes for Python 3 usage. + +* docutils/setup.py + + - Fix [ 3527842 ]. Under Python 3, converted tests and tools were + installed in the PYTHONPATH. Converted tests are now + stored in ``docutils/test3/``, tools no longer need conversion. + + If you installed one of Docutils versions 0.7 ... 0.9 with + ``setup.py install`` under Python 3, remove the spurious + ``test/`` and ``tools/`` directories in the site library root. + + +Release 0.9 (2012-05-02) +========================= + +* General: + + - reStructuredText "code" role and directive with syntax highlighting + by Pygments_. + - "code" option of the "include" directive. + + .. _Pygments: http://pygments.org/ + + - Fix [ 3402314 ] allow non-ASCII whitespace, punctuation + characters and "international" quotes around inline markup. + + - Fix handling of missing stylesheets. + +* setup.py + + - Fix [ 2971827 ] and [ 3442827 ] + extras/roman.py moved to docutils/utils/roman.py + +* docutils/utils.py -> docutils/utils/__init__.py + + - docutils.utils is now a package (providing a place for sub-modules) + +* docutils/writers/html4css1/__init__.py + + - change default for `math-output` setting to MathJax + +* docutils/writers/latex2e/__init__.py + + - Support the `abbreviation` and `acronym` standard roles. + - Record only files required to generate the LaTeX source as dependencies. + - Use ``\setcounter{secnumdepth}{0}`` instead of ``*``-versions + when suppressing LaTeX section numbering. + + +Release 0.8.1 (2011-08-30) +========================== + +* General: + + - Fix [ 3364658 ] (Change last file with Apache license to BSD-2-Clause) + and [ 3395920 ] (correct copyright info for rst.el). + +* docutils/writers/latex2e/__init__.py + + - Clean up Babel language setting. Restores Sphinx compatibility. + + +Release 0.8 (2011-07-07) +======================== + +* COPYING: + + - Some additions to the Docutils core are released under the 2-Clause BSD + license. + +* General: + + - Handle language codes according to `BCP 47`_. + - If the specified langauage is not supported by Docutils, + warn and fall back to English. + - Math support: reStructuredText "math" role and directive, + ``math`` and ``math_block`` doctree elements. + - Orphaned "python" reader and "newlatex2e" writer moved to the sandbox. + + .. _BCP 47: http://www.rfc-editor.org/rfc/bcp/bcp47.txt + +* reStructuredText: + + - most directives now support a "name" option that attaches a + reference name. So you can write :: + + .. figure:: image.png + :name: figure name + + as a short form of :: + + .. _figure name: + + .. figure:: image.png + +Internationalization: + +* Added lithuanian mappings. + +Components: + +* HTML writer: + + - New setting "math-output" with support for HTML, MathML, and LaTeX. + +* LaTeX2e writer: + + - Convert image URI to a local file path. + - Apply [ 3148141 ] fix multicolumn support when a colspanning cell + has more than one paragraph (Wolfgang Scherer). + +* XeTeX writer: + + - New writer generating LaTeX code for compiling with ``xelatex``. + + XeTeX uses unicode and modern font technologies. + +* and fixes and enhancements here and there. + + +Release 0.7 (2010-07-07) +======================== + +Components: + +* HTML writer: + + - Support SVG and SWF images (thanks to Stefan Rank). + - Generate valid XHTML for centered images with targets. + Use CSS classes instead of "align" tags for image alignment. + +* LaTeX2e writer: + + - Use the ``\url`` command for URLs (breaks long URLs instead of writing + into the margin). + - Preserve runs of spaces in 'inline literals'. + - Deprecate ``figure_footnotes`` setting. + - Rename ``use_latex_footnotes`` setting to `docutils_footnotes`__. + - New ``latex_preamble`` setting. + - Use PDF standard fonts (Times/Helvetica/Courier) as default. + - `hyperref` package called with ``unicode`` option (see the + `hyperref config tips`__ for how to override). + - Drop the special `output_encoding`__ default ("latin-1"). + The Docutils wide default (usually "UTF-8") is used instead. + +__ docs/user/config.html#docutils-footnotes +__ docs/user/latex.html#hyperlinks +__ docs/user/latex.html#output-encoding + +* manpage writer: + + - Titles level 1, that is ``.SH``, always uppercase. + - Apply patch from mg: literal text should be bold in man-pages. + +General: + +* io.FileInput opens files as text files with universal newline support + (mode "rU", configurable with the new optional argument "mode"). + +* setup.py: + + - Python 3 support: copy test/ and tools/ to the build-dir + and convert Python sources with 2to3. + + +Release 0.6 (2009-10-11) +======================== + +.. Note:: + + Docutils 0.5 is the last version supporting Python 2.2. + + Docutils 0.6 is compatible with Python versions from 2.3 up to 2.6 + and convertible to 3.1 code. + +.. note:: + + The "newlatex" writer is orphaned. + + The recommended way to generate PDF output is to use either the + LaTeX2e writer or one of the alternatives listed at + http://docutils.sourceforge.net/docs/user/links.html#pdf. + +* reStructuredText: + + - Allow length units for all length specifications. + - Allow percent sign in "scale" argument of "figure" and "image" directives. + - Bugfix: The "figalign" argument of a figure now works as intended + (aligning the figure not its contents). + - Align images with class "align-[right|center|left]" + (allows setting the alignment of an image in a figure). + - Hard tabs in literal inclusions are replaced by spaces. This is + configurable via the new "tab-width" option of the "include" directive + (a negative tab-width prevents tab expansion). + +* HTML writer: + + - ``--stylesheet`` and ``--stylesheet-path`` options now support a comma + separated list of stylesheets. + +* LaTeX2e writer: + + - New defaults: + - font-encoding: "T1" (formerly implicitely set by 'ae'). + - use-latex-toc: true (ToC with page numbers). + - use-latex-footnotes: true (no mixup with figures). + - Float placement defaults to "here definitely" (configurable). + - Align of image in a figure defaults to 'center'. + - Use class defaults for page margins ('typearea' now optional). + - Support LaTeX packages as ``--stylesheet`` arguments. + - Use ``bp`` for lengths without unit or unit ``pt``, + do not convert ``px`` to ``pt``. + - Do not use 'ae' and 'aeguill' packages if font-encoding is set to ''. + - Set sub- and superscript role argument as text not math. + - Support custom roles based on standard roles. + - Load packages and define macros only if required in the document. + - All Docutils specific LaTeX macros are prefixed with ``DU``. + - Better conformance to Docutils specifications with "use_latex_toc". + - If 'sectnum_xform' is False, the 'sectnum' directive triggers + section numbering by LaTeX. + - Use default font in admonitions and sidebar. + - Typeset generic topic as "quote with title". + - Use template (file and configuration option). + - Render doctest blocks as literal blocks (indented). + +* ODT writer: + + - moved from sandbox to Doctutils core. + +* manpage writer: + + - moved from sandbox to Doctutils core. + + +Release 0.5 (2008-06-25) +======================== + +Components: + +* HTML writer. + + - Dropped all ``name`` attributes of ``a`` elements (``id`` is + universally supported now). + +* LaTeX2e writer: + + - Better bibTeX citation support. + - Add ``--literal-block-env`` + +* PEP writer: + + - Changed to support new python.org website structure and + pep2pyramid.py. + +reStructuredText: + +* Changed the directive API to a new object-oriented system. + (Compatibility for the old, functional-style directive interface is + retained.) See the updated `Creating reStructuredText Directives`__ + how-to. + + __ docs/howto/rst-directives.html + +* Allow ``+`` and ``:`` in reference names requested for citations. + +Documentation: + +* Added `Deploying Docutils Securely`__ + + __ docs/howto/security.txt + +Internationalization: + +* Added hebrew mappings. + +General: + +* Configuration files are now assumed and required to be + UTF-8-encoded. + +* Added docutils/writers/html4css1/template.txt. + +* Enhance emacs support. + + +Release 0.4 (2006-01-09) +======================== + +.. Note:: + + Docutils 0.4.x is the last version that will support Python 2.1. + Docutils 0.5 will *not* be compatible with Python 2.1; Python 2.2 + or later will be required. + + Docutils 0.4.x is the last version that will make compromises in + its HTML output for Netscape Navigator 4. Docutils 0.5 will + require more up-to-date browsers (the exact definition is to be + determined). + +Components: + +* Added an `S5/HTML writer`__ and the rst2s5.py__ front end: + multi-platform, multi-browser HTML slide shows. + + __ docs/user/slide-shows.html + __ docs/user/tools.html#rst2s5-py + +* The newlatex2e writer is nearing completion. + +* Added a DocTree reader, ``publish_doctree`` and + ``publish_from_doctree`` convenience functions, for document tree + extraction and reprocessing. + +reStructuredText: + +* Added directives: "container__" (generic block-level container), + "default-role__" (role used for \`backtick\` syntax), "title__" + (document title metadata), and "date__" (generate the current local + date, for substitution definitions). + + __ docs/ref/rst/directives.html#container + __ docs/ref/rst/directives.html#default-role + __ docs/ref/rst/directives.html#title + __ docs/ref/rst/directives.html#date + +* Length units are now supported for image__ sizes. + + __ docs/ref/rst/directives.html#image + +* Added `standard definition files`__ for special characters etc. + + __ docs/ref/rst/definitions.html + +Internationalization: + +* Added Japanese and Simplified Chinese language mappings, and support + for double-width CJK-characters in tables and section titles. + +Documentation: + +* Added a `guide for distributors`__ (package maintainers) and a + `guide for developers`__. + + __ docs/dev/distributing.html + __ docs/dev/hacking.html + +General: + +* Added significant `Emacs support for reST`__. + + __ docs/user/emacs.html + +* Added a `--strip-comments`__ option. + + __ docs/user/config.html#strip-comments + +* `--embed-stylesheet`__ is now the default for the HTML writer + (rather than --link-stylesheet). + + __ docs/user/config.html#embed-stylesheet + + +Release 0.3.9 (2005-05-26) +========================== + +* Added "file_insertion_enabled__" and "raw_enabled__" settings. + + __ docs/user/config.html#file-insertion-enabled + __ docs/user/config.html#raw-enabled + +* Added `auto-enumerated lists`__. + + __ docs/ref/rst/restructuredtext.html#enumerated-lists + +* Added `"header" and "footer"`__ directives. + + __ docs/ref/rst/directives.html#document-header-footer + +* Added "list-table__" directive. + + __ docs/ref/rst/directives.html#list-table + +* Added support for `section subtitles`__. + + __ docs/user/config.html#sectsubtitle-xform + +* Added "field_name_limit__" and "option_limit__" settings to HTML writer. + + __ docs/user/config.html#field-name-limit + __ docs/user/config.html#option-limit + +* Added "cloak_email_addresses__" setting to HTML writer. + + __ docs/user/config.html#cloak-email-addresses + +* UTF-8 BOMs are now removed from the input stream. + + +Release 0.3.7 (2004-12-24) +========================== + +* A special "`line block`__" syntax has been added. (Also see the + `quick reference`__.) + + __ docs/ref/rst/restructuredtext.html#line-blocks + __ docs/user/rst/quickref.html#line-blocks + +* Empty sections are now allowed. + +* A "raw__" role has been added. + + __ docs/ref/rst/roles.html#raw + +* The LaTeX writer now escapes consecutive dashes (like "--" or "---") + so that they are no longer transformed by LaTeX to en or em dashes. + (Please see the FAQ__ for how to represent such dashes.) + + __ FAQ.html#how-can-i-represent-esoteric-characters-e-g-character-entities-in-a-document + +* A `dependency recorder`__ has been added. + + __ docs/user/config.html#record-dependencies + +* A directive has been added for `compound paragraphs`__. + + __ docs/ref/rst/directives.html#compound-paragraph + + +Release 0.3.5 (2004-07-29) +========================== + +* Improved, extended and reorganized the documentation__. + + __ docs/index.html + +* Added "csv-table__" directive. + + __ docs/ref/rst/directives.html#csv-table diff --git a/docutils/__init__.py b/docutils/__init__.py new file mode 100644 index 0000000..f4a81e3 --- /dev/null +++ b/docutils/__init__.py @@ -0,0 +1,262 @@ +# $Id: __init__.py 8147 2017-08-03 09:01:16Z grubert $ +# Author: David Goodger <goodger@python.org> +# Copyright: This module has been placed in the public domain. + +""" +This is the Docutils (Python Documentation Utilities) package. + +Package Structure +================= + +Modules: + +- __init__.py: Contains component base classes, exception classes, and + Docutils version information. + +- core.py: Contains the ``Publisher`` class and ``publish_*()`` convenience + functions. + +- frontend.py: Runtime settings (command-line interface, configuration files) + processing, for Docutils front-ends. + +- io.py: Provides a uniform API for low-level input and output. + +- nodes.py: Docutils document tree (doctree) node class library. + +- statemachine.py: A finite state machine specialized for + regular-expression-based text filters. + +Subpackages: + +- languages: Language-specific mappings of terms. + +- parsers: Syntax-specific input parser modules or packages. + +- readers: Context-specific input handlers which understand the data + source and manage a parser. + +- transforms: Modules used by readers and writers to modify DPS + doctrees. + +- utils: Contains the ``Reporter`` system warning class and miscellaneous + utilities used by readers, writers, and transforms. + + utils/urischemes.py: Contains a complete mapping of known URI addressing + scheme names to descriptions. + +- utils/math: Contains functions for conversion of mathematical notation + between different formats (LaTeX, MathML, text, ...). + +- writers: Format-specific output translators. +""" + +import sys + + +__docformat__ = 'reStructuredText' + +__version__ = '0.14' +"""Docutils version identifier (complies with PEP 440):: + + major.minor[.micro][releaselevel[serial]][.dev] + +* The major number will be bumped when the project is feature-complete, and + later if there is a major change in the design or API. +* The minor number is bumped whenever there are new features. +* The micro number is bumped for bug-fix releases. Omitted if micro=0. +* The releaselevel identifier is used for pre-releases, one of 'a' (alpha), + 'b' (beta), or 'rc' (release candidate). Omitted for final releases. +* The serial release number identifies prereleases; omitted if 0. +* The '.dev' suffix indicates active development, not a release, before the + version indicated. + +For version comparison operations, use `__version_info__` +rather than parsing the text of `__version__`. +""" + +# workaround for Python < 2.6: +__version_info__ = (0, 14, 0, 'final', 0, True) +# To add in Docutils 0.15, replacing the line above: +""" +from collections import namedtuple +VersionInfo = namedtuple( + 'VersionInfo', 'major minor micro releaselevel serial release') +__version_info__ = VersionInfo( + major=0, + minor=15, + micro=0, + releaselevel='alpha', # development status: + # one of 'alpha', 'beta', 'candidate', 'final' + serial=0, # pre-release number (0 for final releases) + release=False # True for official releases and pre-releases + ) + +Comprehensive version information tuple. Can be used to test for a +minimally required version, e.g. :: + + if __version_info__ >= (0, 13, 0, 'candidate', 2, True) + +or in a self-documenting way like :: + + if __version_info__ >= docutils.VersionInfo( + major=0, minor=13, micro=0, + releaselevel='candidate', serial=2, release=True) +""" + +__version_details__ = '' +"""Optional extra version details (e.g. 'snapshot 2005-05-29, r3410'). +(For development and release status see `__version_info__`.) +""" + + +class ApplicationError(StandardError): + # Workaround: + # In Python < 2.6, unicode(<exception instance>) calls `str` on the + # arg and therefore, e.g., unicode(StandardError(u'\u234')) fails + # with UnicodeDecodeError. + if sys.version_info < (2,6): + def __unicode__(self): + return u', '.join(self.args) + + +class DataError(ApplicationError): pass + + +class SettingsSpec: + + """ + Runtime setting specification base class. + + SettingsSpec subclass objects used by `docutils.frontend.OptionParser`. + """ + + settings_spec = () + """Runtime settings specification. Override in subclasses. + + Defines runtime settings and associated command-line options, as used by + `docutils.frontend.OptionParser`. This is a tuple of: + + - Option group title (string or `None` which implies no group, just a list + of single options). + + - Description (string or `None`). + + - A sequence of option tuples. Each consists of: + + - Help text (string) + + - List of option strings (e.g. ``['-Q', '--quux']``). + + - Dictionary of keyword arguments sent to the OptionParser/OptionGroup + ``add_option`` method. + + Runtime setting names are derived implicitly from long option names + ('--a-setting' becomes ``settings.a_setting``) or explicitly from the + 'dest' keyword argument. + + Most settings will also have a 'validator' keyword & function. The + validator function validates setting values (from configuration files + and command-line option arguments) and converts them to appropriate + types. For example, the ``docutils.frontend.validate_boolean`` + function, **required by all boolean settings**, converts true values + ('1', 'on', 'yes', and 'true') to 1 and false values ('0', 'off', + 'no', 'false', and '') to 0. Validators need only be set once per + setting. See the `docutils.frontend.validate_*` functions. + + See the optparse docs for more details. + + - More triples of group title, description, options, as many times as + needed. Thus, `settings_spec` tuples can be simply concatenated. + """ + + settings_defaults = None + """A dictionary of defaults for settings not in `settings_spec` (internal + settings, intended to be inaccessible by command-line and config file). + Override in subclasses.""" + + settings_default_overrides = None + """A dictionary of auxiliary defaults, to override defaults for settings + defined in other components. Override in subclasses.""" + + relative_path_settings = () + """Settings containing filesystem paths. Override in subclasses. + Settings listed here are to be interpreted relative to the current working + directory.""" + + config_section = None + """The name of the config file section specific to this component + (lowercase, no brackets). Override in subclasses.""" + + config_section_dependencies = None + """A list of names of config file sections that are to be applied before + `config_section`, in order (from general to specific). In other words, + the settings in `config_section` are to be overlaid on top of the settings + from these sections. The "general" section is assumed implicitly. + Override in subclasses.""" + + +class TransformSpec: + + """ + Runtime transform specification base class. + + TransformSpec subclass objects used by `docutils.transforms.Transformer`. + """ + + def get_transforms(self): + """Transforms required by this class. Override in subclasses.""" + if self.default_transforms != (): + import warnings + warnings.warn('default_transforms attribute deprecated.\n' + 'Use get_transforms() method instead.', + DeprecationWarning) + return list(self.default_transforms) + return [] + + # Deprecated; for compatibility. + default_transforms = () + + unknown_reference_resolvers = () + """List of functions to try to resolve unknown references. Unknown + references have a 'refname' attribute which doesn't correspond to any + target in the document. Called when the transforms in + `docutils.tranforms.references` are 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.''' + + If the function is able to resolve the reference, it should also remove + the 'refname' attribute and mark the node as resolved:: + + del node['refname'] + node.resolved = 1 + + 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 + """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? + + To be used by transforms to ask the dependent component if it supports + a certain input context or output format. + """ + return format in self.supported diff --git a/docutils/transforms/__init__.py b/docutils/transforms/__init__.py new file mode 100644 index 0000000..5b6926a --- /dev/null +++ b/docutils/transforms/__init__.py @@ -0,0 +1,172 @@ +# $Id: __init__.py 6433 2010-09-28 08:21:25Z milde $ +# Authors: David Goodger <goodger@python.org>; Ueli Schlaepfer +# Copyright: This module has been placed in the public domain. + +""" +This package contains modules for standard tree transforms available +to Docutils components. Tree transforms serve a variety of purposes: + +- To tie up certain syntax-specific "loose ends" that remain after the + initial parsing of the input plaintext. These transforms are used to + supplement a limited syntax. + +- To automate the internal linking of the document tree (hyperlink + references, footnote references, etc.). + +- To extract useful information from the document tree. These + transforms may be used to construct (for example) indexes and tables + of contents. + +Each transform is an optional step that a Docutils component may +choose to perform on the parsed document. +""" + +__docformat__ = 'reStructuredText' + + +from docutils import languages, ApplicationError, TransformSpec + + +class TransformError(ApplicationError): pass + + +class Transform: + + """ + Docutils transform component abstract base class. + """ + + default_priority = None + """Numerical priority of this transform, 0 through 999 (override).""" + + def __init__(self, document, startnode=None): + """ + Initial setup for in-place document transforms. + """ + + self.document = document + """The document tree to transform.""" + + self.startnode = startnode + """Node from which to begin the transform. For many transforms which + apply to the document as a whole, `startnode` is not set (i.e. its + value is `None`).""" + + self.language = languages.get_language( + document.settings.language_code, document.reporter) + """Language module local to this document.""" + + def apply(self, **kwargs): + """Override to apply the transform to the document tree.""" + raise NotImplementedError('subclass must override this method') + + +class Transformer(TransformSpec): + + """ + Stores transforms (`Transform` classes) and applies them to document + trees. Also keeps track of components by component type name. + """ + + def __init__(self, document): + self.transforms = [] + """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.""" + + self.applied = [] + """Transforms already applied, in order.""" + + self.sorted = 0 + """Boolean: is `self.tranforms` sorted?""" + + self.components = {} + """Mapping of component type name to component object. Set by + `self.populate_from_components()`.""" + + self.serialno = 0 + """Internal serial number to keep track of the add order of + transforms.""" + + def add_transform(self, transform_class, priority=None, **kwargs): + """ + Store a single transform. Use `priority` to override the default. + `kwargs` is a dictionary whose contents are passed as keyword + arguments to the `apply` method of the transform. This can be used to + pass application-specific data to the transform instance. + """ + if priority is None: + priority = transform_class.default_priority + priority_string = self.get_priority_string(priority) + self.transforms.append( + (priority_string, transform_class, None, kwargs)) + self.sorted = 0 + + def add_transforms(self, transform_list): + """Store multiple transforms, with default priorities.""" + for transform_class in transform_list: + priority_string = self.get_priority_string( + transform_class.default_priority) + self.transforms.append( + (priority_string, transform_class, None, {})) + self.sorted = 0 + + def add_pending(self, pending, priority=None): + """Store a transform with an associated `pending` node.""" + transform_class = pending.transform + if priority is None: + priority = transform_class.default_priority + priority_string = self.get_priority_string(priority) + self.transforms.append( + (priority_string, transform_class, pending, {})) + self.sorted = 0 + + def get_priority_string(self, priority): + """ + Return a string, `priority` combined with `self.serialno`. + + This ensures FIFO order on transforms with identical priority. + """ + self.serialno += 1 + return '%03d-%03d' % (priority, self.serialno) + + def populate_from_components(self, components): + """ + Store each component's default transforms, with default priorities. + Also, store components by type name in a mapping for later lookup. + """ + for component in components: + if component is None: + continue + self.add_transforms(component.get_transforms()) + self.components[component.component_type] = component + self.sorted = 0 + # Set up 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( + self.document.note_transform_message) + while self.transforms: + if not self.sorted: + # Unsorted initially, and whenever a transform is added. + self.transforms.sort() + self.transforms.reverse() + self.sorted = 1 + priority, transform_class, pending, kwargs = self.transforms.pop() + transform = transform_class(self.document, startnode=pending) + transform.apply(**kwargs) + self.applied.append((priority, transform_class, pending, kwargs)) diff --git a/docutils/transforms/components.py b/docutils/transforms/components.py new file mode 100644 index 0000000..d3e548c --- /dev/null +++ b/docutils/transforms/components.py @@ -0,0 +1,52 @@ +# $Id: components.py 4564 2006-05-21 20:44:42Z wiemann $ +# Author: David Goodger <goodger@python.org> +# Copyright: This module has been placed in the public domain. + +""" +Docutils component-related transforms. +""" + +__docformat__ = 'reStructuredText' + +import sys +import os +import re +import time +from docutils import nodes, utils +from docutils import ApplicationError, DataError +from docutils.transforms import Transform, TransformError + + +class Filter(Transform): + + """ + Include or exclude elements which depend on a specific Docutils component. + + For use with `nodes.pending` elements. A "pending" element's dictionary + attribute ``details`` must contain the keys "component" and "format". The + value of ``details['component']`` must match the type name of the + component the elements depend on (e.g. "writer"). The value of + ``details['format']`` is the name of a specific format or context of that + component (e.g. "html"). If the matching Docutils component supports that + format or context, the "pending" element is replaced by the contents of + ``details['nodes']`` (a list of nodes); otherwise, the "pending" element + is removed. + + For example, the reStructuredText "meta" directive creates a "pending" + element containing a "meta" element (in ``pending.details['nodes']``). + Only writers (``pending.details['component'] == 'writer'``) supporting the + "html" format (``pending.details['format'] == 'html'``) will include the + "meta" element; it will be deleted from the output of all other writers. + """ + + default_priority = 780 + + def apply(self): + pending = self.startnode + component_type = pending.details['component'] # 'reader' or 'writer' + format = pending.details['format'] + component = self.document.transformer.components[component_type] + if component.supports(format): + pending.replace_self(pending.details['nodes']) + else: + pending.parent.remove(pending) diff --git a/docutils/transforms/frontmatter.py b/docutils/transforms/frontmatter.py new file mode 100644 index 0000000..92287da --- /dev/null +++ b/docutils/transforms/frontmatter.py @@ -0,0 +1,532 @@ +# $Id: frontmatter.py 8117 2017-06-18 23:38:18Z milde $ +# Author: David Goodger, Ueli Schlaepfer <goodger@python.org> +# Copyright: This module has been placed in the public domain. + +""" +Transforms related to the front matter of a document or a section +(information found before the main text): + +- `DocTitle`: Used to transform a lone top level section's title to + the document title, promote a remaining lone top-level section's + title to the document subtitle, and determine the document's title + metadata (document['title']) based on the document title and/or the + "title" setting. + +- `SectionSubTitle`: Used to transform a lone subsection into a + subtitle. + +- `DocInfo`: Used to transform a bibliographic field list into docinfo + elements. +""" + +__docformat__ = 'reStructuredText' + +import re +from docutils import nodes, utils +from docutils.transforms import TransformError, Transform + + +class TitlePromoter(Transform): + + """ + Abstract base class for DocTitle and SectionSubTitle transforms. + """ + + def promote_title(self, node): + """ + Transform the following tree:: + + <node> + <section> + <title> + ... + + into :: + + <node> + <title> + ... + + `node` is normally a document. + """ + # Type check + if not isinstance(node, nodes.Element): + raise TypeError, 'node must be of Element-derived type.' + + # `node` must not have a title yet. + assert not (len(node) and isinstance(node[0], nodes.title)) + section, index = self.candidate_index(node) + if index is None: + return None + + # Transfer the section's attributes to the node: + # NOTE: Change second parameter to False to NOT replace + # attributes that already exist in node with those in + # section + # NOTE: Remove third parameter to NOT copy the 'source' + # attribute from section + node.update_all_atts_concatenating(section, True, True) + + # setup_child is called automatically for all nodes. + node[:] = (section[:1] # section title + + node[:index] # everything that was in the + # node before the section + + section[1:]) # everything that was in the section + assert isinstance(node[0], nodes.title) + return 1 + + def promote_subtitle(self, node): + """ + Transform the following node tree:: + + <node> + <title> + <section> + <title> + ... + + into :: + + <node> + <title> + <subtitle> + ... + """ + # Type check + if not isinstance(node, nodes.Element): + raise TypeError, 'node must be of Element-derived type.' + + subsection, index = self.candidate_index(node) + if index is None: + return None + subtitle = nodes.subtitle() + + # Transfer the subsection's attributes to the new subtitle + # NOTE: Change second parameter to False to NOT replace + # attributes that already exist in node with those in + # section + # NOTE: Remove third parameter to NOT copy the 'source' + # attribute from section + subtitle.update_all_atts_concatenating(subsection, True, True) + + # Transfer the contents of the subsection's title to the + # subtitle: + subtitle[:] = subsection[0][:] + node[:] = (node[:1] # title + + [subtitle] + # everything that was before the section: + + node[1:index] + # everything that was in the subsection: + + subsection[1:]) + return 1 + + def candidate_index(self, node): + """ + Find and return the promotion candidate and its index. + + Return (None, None) if no valid candidate was found. + """ + index = node.first_child_not_matching_class( + nodes.PreBibliographic) + if index is None or len(node) > (index + 1) or \ + not isinstance(node[index], nodes.section): + return None, None + else: + return node[index], index + + +class DocTitle(TitlePromoter): + + """ + In reStructuredText_, there is no way to specify a document title + and subtitle explicitly. Instead, we can supply the document title + (and possibly the subtitle as well) implicitly, and use this + two-step transform to "raise" or "promote" the title(s) (and their + corresponding section contents) to the document level. + + 1. If the document contains a single top-level section as its + first non-comment element, the top-level section's title + becomes the document's title, and the top-level section's + contents become the document's immediate contents. The lone + top-level section header must be the first non-comment element + in the document. + + For example, take this input text:: + + ================= + Top-Level Title + ================= + + A paragraph. + + Once parsed, it looks like this:: + + <document> + <section names="top-level title"> + <title> + Top-Level Title + <paragraph> + A paragraph. + + After running the DocTitle transform, we have:: + + <document names="top-level title"> + <title> + Top-Level Title + <paragraph> + A paragraph. + + 2. If step 1 successfully determines the document title, we + continue by checking for a subtitle. + + If the lone top-level section itself contains a single + second-level section as its first non-comment element, that + section's title is promoted to the document's subtitle, and + that section's contents become the document's immediate + contents. Given this input text:: + + ================= + Top-Level Title + ================= + + Second-Level Title + ~~~~~~~~~~~~~~~~~~ + + A paragraph. + + After parsing and running the Section Promotion transform, the + result is:: + + <document names="top-level title"> + <title> + Top-Level Title + <subtitle names="second-level title"> + Second-Level Title + <paragraph> + A paragraph. + + (Note that the implicit hyperlink target generated by the + "Second-Level Title" is preserved on the "subtitle" element + itself.) + + Any comment elements occurring before the document title or + subtitle are accumulated and inserted as the first body elements + after the title(s). + + This transform also sets the document's metadata title + (document['title']). + + .. _reStructuredText: http://docutils.sf.net/rst.html + """ + + default_priority = 320 + + def set_metadata(self): + """ + Set document['title'] metadata title from the following + sources, listed in order of priority: + + * Existing document['title'] attribute. + * "title" setting. + * Document title node (as promoted by promote_title). + """ + if not self.document.hasattr('title'): + if self.document.settings.title is not None: + self.document['title'] = self.document.settings.title + elif len(self.document) and isinstance(self.document[0], nodes.title): + self.document['title'] = self.document[0].astext() + + def apply(self): + if getattr(self.document.settings, 'doctitle_xform', 1): + # promote_(sub)title defined in TitlePromoter base class. + if self.promote_title(self.document): + # If a title has been promoted, also try to promote a + # subtitle. + self.promote_subtitle(self.document) + # Set document['title']. + self.set_metadata() + + +class SectionSubTitle(TitlePromoter): + + """ + This works like document subtitles, but for sections. For example, :: + + <section> + <title> + Title + <section> + <title> + Subtitle + ... + + is transformed into :: + + <section> + <title> + Title + <subtitle> + Subtitle + ... + + For details refer to the docstring of DocTitle. + """ + + default_priority = 350 + + def apply(self): + if not getattr(self.document.settings, 'sectsubtitle_xform', 1): + return + for section in self.document.traverse(nodes.section): + # On our way through the node tree, we are deleting + # sections, but we call self.promote_subtitle for those + # sections nonetheless. To do: Write a test case which + # shows the problem and discuss on Docutils-develop. + self.promote_subtitle(section) + + +class DocInfo(Transform): + + """ + This transform is specific to the reStructuredText_ markup syntax; + see "Bibliographic Fields" in the `reStructuredText Markup + Specification`_ for a high-level description. This transform + should be run *after* the `DocTitle` transform. + + Given a field list as the first non-comment element after the + document title and subtitle (if present), registered bibliographic + field names are transformed to the corresponding DTD elements, + becoming child elements of the "docinfo" element (except for a + dedication and/or an abstract, which become "topic" elements after + "docinfo"). + + For example, given this document fragment after parsing:: + + <document> + <title> + Document Title + <field_list> + <field> + <field_name> + Author + <field_body> + <paragraph> + A. Name + <field> + <field_name> + Status + <field_body> + <paragraph> + $RCSfile$ + ... + + After running the bibliographic field list transform, the + resulting document tree would look like this:: + + <document> + <title> + Document Title + <docinfo> + <author> + A. Name + <status> + frontmatter.py + ... + + The "Status" field contained an expanded RCS keyword, which is + normally (but optionally) cleaned up by the transform. The sole + contents of the field body must be a paragraph containing an + expanded RCS keyword of the form "$keyword: expansion text $". Any + RCS keyword can be processed in any bibliographic field. The + dollar signs and leading RCS keyword name are removed. Extra + processing is done for the following RCS keywords: + + - "RCSfile" expands to the name of the file in the RCS or CVS + repository, which is the name of the source file with a ",v" + suffix appended. The transform will remove the ",v" suffix. + + - "Date" expands to the format "YYYY/MM/DD hh:mm:ss" (in the UTC + time zone). The RCS Keywords transform will extract just the + date itself and transform it to an ISO 8601 format date, as in + "2000-12-31". + + (Since the source file for this text is itself stored under CVS, + we can't show an example of the "Date" RCS keyword because we + can't prevent any RCS keywords used in this explanation from + being expanded. Only the "RCSfile" keyword is stable; its + expansion text changes only if the file name changes.) + + .. _reStructuredText: http://docutils.sf.net/rst.html + .. _reStructuredText Markup Specification: + http://docutils.sf.net/docs/ref/rst/restructuredtext.html + """ + + default_priority = 340 + + biblio_nodes = { + 'author': nodes.author, + 'authors': nodes.authors, + 'organization': nodes.organization, + 'address': nodes.address, + 'contact': nodes.contact, + 'version': nodes.version, + 'revision': nodes.revision, + 'status': nodes.status, + 'date': nodes.date, + 'copyright': nodes.copyright, + 'dedication': nodes.topic, + 'abstract': nodes.topic} + """Canonical field name (lowcased) to node class name mapping for + bibliographic fields (field_list).""" + + def apply(self): + if not getattr(self.document.settings, 'docinfo_xform', 1): + return + document = self.document + index = document.first_child_not_matching_class( + nodes.PreBibliographic) + if index is None: + return + candidate = document[index] + if isinstance(candidate, nodes.field_list): + biblioindex = document.first_child_not_matching_class( + (nodes.Titular, nodes.Decorative)) + nodelist = self.extract_bibliographic(candidate) + del document[index] # untransformed field list (candidate) + document[biblioindex:biblioindex] = nodelist + + def extract_bibliographic(self, field_list): + docinfo = nodes.docinfo() + bibliofields = self.language.bibliographic_fields + labels = self.language.labels + topics = {'dedication': None, 'abstract': None} + for field in field_list: + try: + name = field[0][0].astext() + normedname = nodes.fully_normalize_name(name) + if not (len(field) == 2 and normedname in bibliofields + and self.check_empty_biblio_field(field, name)): + raise TransformError + canonical = bibliofields[normedname] + biblioclass = self.biblio_nodes[canonical] + if issubclass(biblioclass, nodes.TextElement): + if not self.check_compound_biblio_field(field, name): + raise TransformError + utils.clean_rcs_keywords( + field[1][0], self.rcs_keyword_substitutions) + docinfo.append(biblioclass('', '', *field[1][0])) + elif issubclass(biblioclass, nodes.authors): + self.extract_authors(field, name, docinfo) + elif issubclass(biblioclass, nodes.topic): + if topics[canonical]: + field[-1] += self.document.reporter.warning( + 'There can only be one "%s" field.' % name, + base_node=field) + raise TransformError + title = nodes.title(name, labels[canonical]) + topics[canonical] = biblioclass( + '', title, classes=[canonical], *field[1].children) + else: + docinfo.append(biblioclass('', *field[1].children)) + except TransformError: + if len(field[-1]) == 1 \ + and isinstance(field[-1][0], nodes.paragraph): + utils.clean_rcs_keywords( + field[-1][0], self.rcs_keyword_substitutions) + if normedname not in bibliofields: + classvalue = nodes.make_id(normedname) + if classvalue: + field['classes'].append(classvalue) + docinfo.append(field) + nodelist = [] + if len(docinfo) != 0: + nodelist.append(docinfo) + for name in ('dedication', 'abstract'): + if topics[name]: + nodelist.append(topics[name]) + return nodelist + + def check_empty_biblio_field(self, field, name): + if len(field[-1]) < 1: + field[-1] += self.document.reporter.warning( + 'Cannot extract empty bibliographic field "%s".' % name, + base_node=field) + return None + return 1 + + def check_compound_biblio_field(self, field, name): + if len(field[-1]) > 1: + field[-1] += self.document.reporter.warning( + 'Cannot extract compound bibliographic field "%s".' % name, + base_node=field) + return None + if not isinstance(field[-1][0], nodes.paragraph): + field[-1] += self.document.reporter.warning( + 'Cannot extract bibliographic field "%s" containing ' + 'anything other than a single paragraph.' % name, + base_node=field) + return None + return 1 + + rcs_keyword_substitutions = [ + (re.compile(r'\$' r'Date: (\d\d\d\d)[-/](\d\d)[-/](\d\d)[ T][\d:]+' + r'[^$]* \$', re.IGNORECASE), r'\1-\2-\3'), + (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: + if len(field[1]) == 1: + if isinstance(field[1][0], nodes.paragraph): + authors = self.authors_from_one_paragraph(field) + elif isinstance(field[1][0], nodes.bullet_list): + authors = self.authors_from_bullet_list(field) + else: + raise TransformError + else: + authors = self.authors_from_paragraphs(field) + authornodes = [nodes.author('', '', *author) + for author in authors if author] + if len(authornodes) >= 1: + docinfo.append(nodes.authors('', *authornodes)) + else: + raise TransformError + except TransformError: + field[-1] += self.document.reporter.warning( + 'Bibliographic field "%s" incompatible with extraction: ' + 'it must contain either a single paragraph (with authors ' + 'separated by one of "%s"), multiple paragraphs (one per ' + 'author), or a bullet list with one paragraph (one author) ' + 'per item.' + % (name, ''.join(self.language.author_separators)), + base_node=field) + raise + + def authors_from_one_paragraph(self, field): + text = field[1][0].astext().strip() + if not text: + raise TransformError + for authorsep in self.language.author_separators: + authornames = text.split(authorsep) + if len(authornames) > 1: + break + authornames = [author.strip() for author in authornames] + authors = [[nodes.Text(author)] for author in authornames if author] + return authors + + def authors_from_bullet_list(self, field): + authors = [] + for item in field[1][0]: + if len(item) != 1 or not isinstance(item[0], nodes.paragraph): + raise TransformError + authors.append(item[0].children) + if not authors: + raise TransformError + return authors + + def authors_from_paragraphs(self, field): + for item in field[1]: + if not isinstance(item, nodes.paragraph): + raise TransformError + authors = [item.children for item in field[1]] + return authors diff --git a/docutils/transforms/misc.py b/docutils/transforms/misc.py new file mode 100644 index 0000000..cd68ee1 --- /dev/null +++ b/docutils/transforms/misc.py @@ -0,0 +1,144 @@ +# $Id: misc.py 6314 2010-04-26 10:04:17Z milde $ +# Author: David Goodger <goodger@python.org> +# Copyright: This module has been placed in the public domain. + +""" +Miscellaneous transforms. +""" + +__docformat__ = 'reStructuredText' + +from docutils import nodes +from docutils.transforms import Transform, TransformError + + +class CallBack(Transform): + + """ + Inserts a callback into a document. The callback is called when the + transform is applied, which is determined by its priority. + + For use with `nodes.pending` elements. Requires a ``details['callback']`` + entry, a bound method or function which takes one parameter: the pending + node. Other data can be stored in the ``details`` attribute or in the + object hosting the callback method. + """ + + default_priority = 990 + + def apply(self): + pending = self.startnode + pending.details['callback'](pending) + pending.parent.remove(pending) + + +class ClassAttribute(Transform): + + """ + Move the "class" attribute specified in the "pending" node into the + immediately following non-comment element. + """ + + default_priority = 210 + + def apply(self): + pending = self.startnode + parent = pending.parent + child = pending + while parent: + # Check for appropriate following siblings: + for index in range(parent.index(child) + 1, len(parent)): + element = parent[index] + if (isinstance(element, nodes.Invisible) or + isinstance(element, nodes.system_message)): + continue + element['classes'] += pending.details['class'] + pending.parent.remove(pending) + return + else: + # At end of section or container; apply to sibling + child = parent + parent = parent.parent + error = self.document.reporter.error( + 'No suitable element following "%s" directive' + % pending.details['directive'], + nodes.literal_block(pending.rawsource, pending.rawsource), + line=pending.line) + pending.replace_self(error) + + +class Transitions(Transform): + + """ + Move transitions at the end of sections up the tree. Complain + on transitions after a title, at the beginning or end of the + document, and after another transition. + + For example, transform this:: + + <section> + ... + <transition> + <section> + ... + + into this:: + + <section> + ... + <transition> + <section> + ... + """ + + default_priority = 830 + + def apply(self): + for node in self.document.traverse(nodes.transition): + self.visit_transition(node) + + def visit_transition(self, node): + index = node.parent.index(node) + error = None + if (index == 0 or + isinstance(node.parent[0], nodes.title) and + (index == 1 or + isinstance(node.parent[1], nodes.subtitle) and + index == 2)): + assert (isinstance(node.parent, nodes.document) or + isinstance(node.parent, nodes.section)) + error = self.document.reporter.error( + 'Document or section may not begin with a transition.', + source=node.source, line=node.line) + elif isinstance(node.parent[index - 1], nodes.transition): + error = self.document.reporter.error( + 'At least one body element must separate transitions; ' + 'adjacent transitions are not allowed.', + source=node.source, line=node.line) + if error: + # Insert before node and update index. + node.parent.insert(index, error) + index += 1 + assert index < len(node.parent) + if index != len(node.parent) - 1: + # No need to move the node. + return + # Node behind which the transition is to be moved. + sibling = node + # While sibling is the last node of its parent. + while index == len(sibling.parent) - 1: + sibling = sibling.parent + # If sibling is the whole document (i.e. it has no parent). + if sibling.parent is None: + # Transition at the end of document. Do not move the + # transition up, and place an error behind. + error = self.document.reporter.error( + 'Document may not end with a transition.', + line=node.line) + node.parent.insert(node.parent.index(node) + 1, error) + return + index = sibling.parent.index(sibling) + # Remove the original transition node. + node.parent.remove(node) + # Insert the transition after the sibling. + sibling.parent.insert(index + 1, node) diff --git a/docutils/transforms/parts.py b/docutils/transforms/parts.py new file mode 100644 index 0000000..ec6eda3 --- /dev/null +++ b/docutils/transforms/parts.py @@ -0,0 +1,180 @@ +# $Id: parts.py 6073 2009-08-06 12:21:10Z milde $ +# Authors: David Goodger <goodger@python.org>; Ueli Schlaepfer; Dmitry Jemerov +# Copyright: This module has been placed in the public domain. + +""" +Transforms related to document parts. +""" + +__docformat__ = 'reStructuredText' + + +import re +import sys +from docutils import nodes, utils +from docutils.transforms import TransformError, Transform + + +class SectNum(Transform): + + """ + Automatically assigns numbers to the titles of document sections. + + It is possible to limit the maximum section level for which the numbers + are added. For those sections that are auto-numbered, the "autonum" + attribute is set, informing the contents table generator that a different + form of the TOC should be used. + """ + + default_priority = 710 + """Should be applied before `Contents`.""" + + def apply(self): + self.maxdepth = self.startnode.details.get('depth', None) + self.startvalue = self.startnode.details.get('start', 1) + self.prefix = self.startnode.details.get('prefix', '') + self.suffix = self.startnode.details.get('suffix', '') + self.startnode.parent.remove(self.startnode) + if self.document.settings.sectnum_xform: + if self.maxdepth is None: + self.maxdepth = sys.maxint + self.update_section_numbers(self.document) + else: # store details for eventual section numbering by the writer + self.document.settings.sectnum_depth = self.maxdepth + self.document.settings.sectnum_start = self.startvalue + self.document.settings.sectnum_prefix = self.prefix + self.document.settings.sectnum_suffix = self.suffix + + def update_section_numbers(self, node, prefix=(), depth=0): + depth += 1 + if prefix: + sectnum = 1 + else: + sectnum = self.startvalue + for child in node: + if isinstance(child, nodes.section): + numbers = prefix + (str(sectnum),) + title = child[0] + # Use   for spacing: + generated = nodes.generated( + '', (self.prefix + '.'.join(numbers) + self.suffix + + u'\u00a0' * 3), + classes=['sectnum']) + title.insert(0, generated) + title['auto'] = 1 + if depth < self.maxdepth: + self.update_section_numbers(child, numbers, depth) + sectnum += 1 + + +class Contents(Transform): + + """ + 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" 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 contains generation + options and provides the location for the generated table of contents (the + startnode is replaced by the table of contents "topic"). + """ + + default_priority = 720 + + def apply(self): + try: # let the writer (or output software) build the contents list? + toc_by_writer = self.document.settings.use_latex_toc + except AttributeError: + toc_by_writer = False + details = self.startnode.details + if 'local' in details: + startnode = self.startnode.parent.parent + while not (isinstance(startnode, nodes.section) + or isinstance(startnode, nodes.document)): + # find the ToC root: a direct ancestor of startnode + startnode = startnode.parent + else: + startnode = self.document + self.toc_id = self.startnode.parent['ids'][0] + if 'backlinks' in details: + self.backlinks = details['backlinks'] + else: + self.backlinks = self.document.settings.toc_backlinks + if toc_by_writer: + # move customization settings to the parent node + self.startnode.parent.attributes.update(details) + self.startnode.parent.remove(self.startnode) + else: + contents = self.build_contents(startnode) + if len(contents): + self.startnode.replace_self(contents) + else: + self.startnode.parent.parent.remove(self.startnode.parent) + + def build_contents(self, node, level=0): + level += 1 + sections = [sect for sect in node if isinstance(sect, nodes.section)] + entries = [] + autonum = 0 + depth = self.startnode.details.get('depth', sys.maxint) + for section in sections: + title = section[0] + auto = title.get('auto') # May be set by SectNum. + entrytext = self.copy_and_filter(title) + reference = nodes.reference('', '', refid=section['ids'][0], + *entrytext) + ref_id = self.document.set_id(reference) + entry = nodes.paragraph('', '', reference) + item = nodes.list_item('', entry) + if ( self.backlinks in ('entry', 'top') + and title.next_node(nodes.reference) is None): + if self.backlinks == 'entry': + title['refid'] = ref_id + elif self.backlinks == 'top': + title['refid'] = self.toc_id + if level < depth: + subsects = self.build_contents(section, level) + item += subsects + entries.append(item) + if entries: + contents = nodes.bullet_list('', *entries) + if auto: + contents['classes'].append('auto-toc') + return contents + else: + return [] + + def copy_and_filter(self, node): + """Return a copy of a title, with references, images, etc. removed.""" + visitor = ContentsFilter(self.document) + node.walkabout(visitor) + return visitor.get_entry_text() + + +class ContentsFilter(nodes.TreeCopyVisitor): + + def get_entry_text(self): + return self.get_tree_copy().children + + def visit_citation_reference(self, node): + raise nodes.SkipNode + + def visit_footnote_reference(self, node): + raise nodes.SkipNode + + def visit_image(self, node): + if node.hasattr('alt'): + self.parent.append(nodes.Text(node['alt'])) + raise nodes.SkipNode + + def ignore_node_but_process_children(self, node): + raise nodes.SkipDeparture + + visit_interpreted = ignore_node_but_process_children + visit_problematic = ignore_node_but_process_children + visit_reference = ignore_node_but_process_children + visit_target = ignore_node_but_process_children diff --git a/docutils/transforms/peps.py b/docutils/transforms/peps.py new file mode 100644 index 0000000..94b47c1 --- /dev/null +++ b/docutils/transforms/peps.py @@ -0,0 +1,305 @@ +# $Id: peps.py 7995 2016-12-10 17:50:59Z milde $ +# Author: David Goodger <goodger@python.org> +# Copyright: This module has been placed in the public domain. + +""" +Transforms for PEP processing. + +- `Headers`: Used to transform a PEP's initial RFC-2822 header. It remains a + field list, but some entries get processed. +- `Contents`: Auto-inserts a table of contents. +- `PEPZero`: Special processing for PEP 0. +""" + +__docformat__ = 'reStructuredText' + +import sys +import os +import re +import time +from docutils import nodes, utils, languages +from docutils import ApplicationError, DataError +from docutils.transforms import Transform, TransformError +from docutils.transforms import parts, references, misc + + +class Headers(Transform): + + """ + Process fields in a PEP's initial RFC-2822 header. + """ + + default_priority = 360 + + pep_url = 'pep-%04d' + pep_cvs_url = ('http://hg.python.org' + '/peps/file/default/pep-%04d.txt') + rcs_keyword_substitutions = ( + (re.compile(r'\$' r'RCSfile: (.+),v \$$', re.IGNORECASE), r'\1'), + (re.compile(r'\$[a-zA-Z]+: (.+) \$$'), r'\1'),) + + def apply(self): + if not len(self.document): + # @@@ replace these DataErrors with proper system messages + raise DataError('Document tree is empty.') + header = self.document[0] + if not isinstance(header, nodes.field_list) or \ + 'rfc2822' not in header['classes']: + raise DataError('Document does not begin with an RFC-2822 ' + 'header; it is not a PEP.') + pep = None + for field in header: + if field[0].astext().lower() == 'pep': # should be the first field + value = field[1].astext() + try: + pep = int(value) + cvs_url = self.pep_cvs_url % pep + except ValueError: + pep = value + cvs_url = None + msg = self.document.reporter.warning( + '"PEP" header must contain an integer; "%s" is an ' + 'invalid value.' % pep, base_node=field) + msgid = self.document.set_id(msg) + prb = nodes.problematic(value, value or '(none)', + refid=msgid) + prbid = self.document.set_id(prb) + msg.add_backref(prbid) + if len(field[1]): + field[1][0][:] = [prb] + else: + field[1] += nodes.paragraph('', '', prb) + break + if pep is None: + raise DataError('Document does not contain an RFC-2822 "PEP" ' + 'header.') + if pep == 0: + # Special processing for PEP 0. + pending = nodes.pending(PEPZero) + self.document.insert(1, pending) + self.document.note_pending(pending) + if len(header) < 2 or header[1][0].astext().lower() != 'title': + raise DataError('No title!') + for field in header: + name = field[0].astext().lower() + body = field[1] + if len(body) > 1: + raise DataError('PEP header field body contains multiple ' + 'elements:\n%s' % field.pformat(level=1)) + elif len(body) == 1: + if not isinstance(body[0], nodes.paragraph): + raise DataError('PEP header field body may only contain ' + 'a single paragraph:\n%s' + % field.pformat(level=1)) + elif name == 'last-modified': + date = time.strftime( + '%d-%b-%Y', + time.localtime(os.stat(self.document['source'])[8])) + if cvs_url: + body += nodes.paragraph( + '', '', nodes.reference('', date, refuri=cvs_url)) + else: + # empty + continue + para = body[0] + if name == 'author': + for node in para: + if isinstance(node, nodes.reference): + node.replace_self(mask_email(node)) + elif name == 'discussions-to': + for node in para: + if isinstance(node, nodes.reference): + node.replace_self(mask_email(node, pep)) + elif name in ('replaces', 'replaced-by', 'requires'): + newbody = [] + space = nodes.Text(' ') + for refpep in re.split(r',?\s+', body.astext()): + pepno = int(refpep) + newbody.append(nodes.reference( + refpep, refpep, + refuri=(self.document.settings.pep_base_url + + self.pep_url % pepno))) + newbody.append(space) + para[:] = newbody[:-1] # drop trailing space + elif name == 'last-modified': + utils.clean_rcs_keywords(para, self.rcs_keyword_substitutions) + if cvs_url: + date = para.astext() + para[:] = [nodes.reference('', date, refuri=cvs_url)] + elif name == 'content-type': + pep_type = para.astext() + uri = self.document.settings.pep_base_url + self.pep_url % 12 + para[:] = [nodes.reference('', pep_type, refuri=uri)] + elif name == 'version' and len(body): + utils.clean_rcs_keywords(para, self.rcs_keyword_substitutions) + + +class Contents(Transform): + + """ + 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): + language = languages.get_language(self.document.settings.language_code, + self.document.reporter) + name = language.labels['contents'] + title = nodes.title('', name) + topic = nodes.topic('', title, classes=['contents']) + name = nodes.fully_normalize_name(name) + if not self.document.has_name(name): + topic['names'].append(name) + self.document.note_implicit_target(topic) + pending = nodes.pending(parts.Contents) + topic += pending + self.document.insert(1, topic) + self.document.note_pending(pending) + + +class TargetNotes(Transform): + + """ + Locate the "References" section, insert a placeholder for an external + target footnote insertion transform at the end, and schedule the + transform to run immediately. + """ + + default_priority = 520 + + def apply(self): + doc = self.document + i = len(doc) - 1 + refsect = copyright = None + while i >= 0 and isinstance(doc[i], nodes.section): + title_words = doc[i][0].astext().lower().split() + if 'references' in title_words: + refsect = doc[i] + break + elif 'copyright' in title_words: + copyright = i + i -= 1 + if not refsect: + refsect = nodes.section() + refsect += nodes.title('', 'References') + doc.set_id(refsect) + if copyright: + # Put the new "References" section before "Copyright": + doc.insert(copyright, refsect) + else: + # Put the new "References" section at end of doc: + doc.append(refsect) + pending = nodes.pending(references.TargetNotes) + refsect.append(pending) + self.document.note_pending(pending, 0) + pending = nodes.pending(misc.CallBack, + details={'callback': self.cleanup_callback}) + refsect.append(pending) + self.document.note_pending(pending, 1) + + def cleanup_callback(self, pending): + """ + Remove an empty "References" section. + + Called after the `references.TargetNotes` transform is complete. + """ + if len(pending.parent) == 2: # <title> and <pending> + pending.parent.parent.remove(pending.parent) + + +class PEPZero(Transform): + + """ + Special processing for PEP 0. + """ + + default_priority =760 + + def apply(self): + visitor = PEPZeroSpecial(self.document) + self.document.walk(visitor) + self.startnode.parent.remove(self.startnode) + + +class PEPZeroSpecial(nodes.SparseNodeVisitor): + + """ + Perform the special processing needed by PEP 0: + + - Mask email addresses. + + - Link PEP numbers in the second column of 4-column tables to the PEPs + themselves. + """ + + pep_url = Headers.pep_url + + def unknown_visit(self, node): + pass + + def visit_reference(self, node): + node.replace_self(mask_email(node)) + + def visit_field_list(self, node): + if 'rfc2822' in node['classes']: + raise nodes.SkipNode + + def visit_tgroup(self, node): + self.pep_table = node['cols'] == 4 + self.entry = 0 + + def visit_colspec(self, node): + self.entry += 1 + if self.pep_table and self.entry == 2: + node['classes'].append('num') + + def visit_row(self, node): + self.entry = 0 + + def visit_entry(self, node): + self.entry += 1 + if self.pep_table and self.entry == 2 and len(node) == 1: + node['classes'].append('num') + p = node[0] + if isinstance(p, nodes.paragraph) and len(p) == 1: + text = p.astext() + try: + pep = int(text) + ref = (self.document.settings.pep_base_url + + self.pep_url % pep) + p[0] = nodes.reference(text, text, refuri=ref) + except ValueError: + pass + + +non_masked_addresses = ('peps@python.org', + 'python-list@python.org', + 'python-dev@python.org') + +def mask_email(ref, pepno=None): + """ + Mask the email address in `ref` and return a replacement node. + + `ref` is returned unchanged if it contains no email address. + + For email addresses such as "user@host", mask the address as "user at + host" (text) to thwart simple email address harvesters (except for those + listed in `non_masked_addresses`). If a PEP number (`pepno`) is given, + return a reference including a default email subject. + """ + if ref.hasattr('refuri') and ref['refuri'].startswith('mailto:'): + if ref['refuri'][8:] in non_masked_addresses: + replacement = ref[0] + else: + replacement_text = ref.astext().replace('@', ' at ') + replacement = nodes.raw('', replacement_text, format='html') + if pepno is None: + return replacement + else: + ref['refuri'] += '?subject=PEP%%20%s' % pepno + ref[:] = [replacement] + return ref + else: + return ref diff --git a/docutils/transforms/references.py b/docutils/transforms/references.py new file mode 100644 index 0000000..f271067 --- /dev/null +++ b/docutils/transforms/references.py @@ -0,0 +1,913 @@ +# $Id: references.py 8067 2017-05-04 20:10:03Z milde $ +# Author: David Goodger <goodger@python.org> +# Copyright: This module has been placed in the public domain. + +""" +Transforms for resolving references. +""" + +__docformat__ = 'reStructuredText' + +import sys +import re +from docutils import nodes, utils +from docutils.transforms import TransformError, Transform + + +class PropagateTargets(Transform): + + """ + Propagate empty internal targets to the next element. + + Given the following nodes:: + + <target ids="internal1" names="internal1"> + <target anonymous="1" ids="id1"> + <target ids="internal2" names="internal2"> + <paragraph> + This is a test. + + PropagateTargets propagates the ids and names of the internal + targets preceding the paragraph to the paragraph itself:: + + <target refid="internal1"> + <target anonymous="1" refid="id1"> + <target refid="internal2"> + <paragraph ids="internal2 id1 internal1" names="internal2 internal1"> + This is a test. + """ + + default_priority = 260 + + def apply(self): + for target in self.document.traverse(nodes.target): + # Only block-level targets without reference (like ".. target:"): + if (isinstance(target.parent, nodes.TextElement) or + (target.hasattr('refid') or target.hasattr('refuri') or + target.hasattr('refname'))): + continue + assert len(target) == 0, 'error: block-level target has children' + next_node = target.next_node(ascend=True) + # Do not move names and ids into Invisibles (we'd lose the + # attributes) or different Targetables (e.g. footnotes). + if (next_node is not None and + ((not isinstance(next_node, nodes.Invisible) and + not isinstance(next_node, nodes.Targetable)) or + isinstance(next_node, nodes.target))): + next_node['ids'].extend(target['ids']) + next_node['names'].extend(target['names']) + # Set defaults for next_node.expect_referenced_by_name/id. + if not hasattr(next_node, 'expect_referenced_by_name'): + next_node.expect_referenced_by_name = {} + if not hasattr(next_node, 'expect_referenced_by_id'): + next_node.expect_referenced_by_id = {} + for id in target['ids']: + # Update IDs to node mapping. + self.document.ids[id] = next_node + # If next_node is referenced by id ``id``, this + # target shall be marked as referenced. + next_node.expect_referenced_by_id[id] = target + for name in target['names']: + next_node.expect_referenced_by_name[name] = target + # If there are any expect_referenced_by_... attributes + # in target set, copy them to next_node. + next_node.expect_referenced_by_name.update( + getattr(target, 'expect_referenced_by_name', {})) + next_node.expect_referenced_by_id.update( + getattr(target, 'expect_referenced_by_id', {})) + # Set refid to point to the first former ID of target + # which is now an ID of next_node. + target['refid'] = target['ids'][0] + # Clear ids and names; they have been moved to + # next_node. + target['ids'] = [] + target['names'] = [] + self.document.note_refid(target) + + +class AnonymousHyperlinks(Transform): + + """ + Link anonymous references to targets. Given:: + + <paragraph> + <reference anonymous="1"> + internal + <reference anonymous="1"> + external + <target anonymous="1" ids="id1"> + <target anonymous="1" ids="id2" refuri="http://external"> + + Corresponding references are linked via "refid" or resolved via "refuri":: + + <paragraph> + <reference anonymous="1" refid="id1"> + text + <reference anonymous="1" refuri="http://external"> + external + <target anonymous="1" ids="id1"> + <target anonymous="1" ids="id2" refuri="http://external"> + """ + + default_priority = 440 + + def apply(self): + anonymous_refs = [] + anonymous_targets = [] + for node in self.document.traverse(nodes.reference): + if node.get('anonymous'): + anonymous_refs.append(node) + for node in self.document.traverse(nodes.target): + if node.get('anonymous'): + anonymous_targets.append(node) + if len(anonymous_refs) \ + != len(anonymous_targets): + msg = self.document.reporter.error( + 'Anonymous hyperlink mismatch: %s references but %s ' + 'targets.\nSee "backrefs" attribute for IDs.' + % (len(anonymous_refs), len(anonymous_targets))) + msgid = self.document.set_id(msg) + for ref in anonymous_refs: + prb = nodes.problematic( + ref.rawsource, ref.rawsource, refid=msgid) + prbid = self.document.set_id(prb) + msg.add_backref(prbid) + ref.replace_self(prb) + return + for ref, target in zip(anonymous_refs, anonymous_targets): + target.referenced = 1 + while True: + if target.hasattr('refuri'): + ref['refuri'] = target['refuri'] + ref.resolved = 1 + break + else: + if not target['ids']: + # Propagated target. + target = self.document.ids[target['refid']] + continue + ref['refid'] = target['ids'][0] + self.document.note_refid(ref) + break + + +class IndirectHyperlinks(Transform): + + """ + a) Indirect external references:: + + <paragraph> + <reference refname="indirect external"> + indirect external + <target id="id1" name="direct external" + refuri="http://indirect"> + <target id="id2" name="indirect external" + refname="direct external"> + + The "refuri" attribute is migrated back to all indirect targets + from the final direct target (i.e. a target not referring to + another indirect target):: + + <paragraph> + <reference refname="indirect external"> + indirect external + <target id="id1" name="direct external" + refuri="http://indirect"> + <target id="id2" name="indirect external" + refuri="http://indirect"> + + Once the attribute is migrated, the preexisting "refname" attribute + is dropped. + + b) Indirect internal references:: + + <target id="id1" name="final target"> + <paragraph> + <reference refname="indirect internal"> + indirect internal + <target id="id2" name="indirect internal 2" + refname="final target"> + <target id="id3" name="indirect internal" + refname="indirect internal 2"> + + Targets which indirectly refer to an internal target become one-hop + indirect (their "refid" attributes are directly set to the internal + target's "id"). References which indirectly refer to an internal + target become direct internal references:: + + <target id="id1" name="final target"> + <paragraph> + <reference refid="id1"> + indirect internal + <target id="id2" name="indirect internal 2" refid="id1"> + <target id="id3" name="indirect internal" refid="id1"> + """ + + default_priority = 460 + + def apply(self): + for target in self.document.indirect_targets: + if not target.resolved: + self.resolve_indirect_target(target) + self.resolve_indirect_references(target) + + def resolve_indirect_target(self, target): + refname = target.get('refname') + if refname is None: + reftarget_id = target['refid'] + else: + reftarget_id = self.document.nameids.get(refname) + if not reftarget_id: + # 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] + reftarget.note_referenced_by(id=reftarget_id) + if isinstance(reftarget, nodes.target) \ + and not reftarget.resolved and reftarget.hasattr('refname'): + if hasattr(target, 'multiply_indirect'): + #and target.multiply_indirect): + #del target.multiply_indirect + self.circular_indirect_reference(target) + return + target.multiply_indirect = 1 + self.resolve_indirect_target(reftarget) # multiply indirect + del target.multiply_indirect + if reftarget.hasattr('refuri'): + target['refuri'] = reftarget['refuri'] + if 'refid' in target: + del target['refid'] + elif reftarget.hasattr('refid'): + target['refid'] = reftarget['refid'] + self.document.note_refid(target) + else: + if reftarget['ids']: + target['refid'] = reftarget_id + self.document.note_refid(target) + else: + self.nonexistent_indirect_target(target) + return + if refname is not None: + del target['refname'] + target.resolved = 1 + + def nonexistent_indirect_target(self, target): + if target['refname'] in self.document.nameids: + 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') + + def indirect_target_error(self, target, explanation): + naming = '' + reflist = [] + if target['names']: + naming = '"%s" ' % target['names'][0] + for name in target['names']: + reflist.extend(self.document.refnames.get(name, [])) + for id in target['ids']: + reflist.extend(self.document.refids.get(id, [])) + if target['ids']: + naming += '(id="%s")' % target['ids'][0] + msg = self.document.reporter.error( + 'Indirect hyperlink target %s refers to target "%s", %s.' + % (naming, target['refname'], explanation), base_node=target) + msgid = self.document.set_id(msg) + for ref in utils.uniq(reflist): + prb = nodes.problematic( + ref.rawsource, ref.rawsource, refid=msgid) + prbid = self.document.set_id(prb) + msg.add_backref(prbid) + ref.replace_self(prb) + target.resolved = 1 + + def resolve_indirect_references(self, target): + if target.hasattr('refid'): + attname = 'refid' + call_method = self.document.note_refid + elif target.hasattr('refuri'): + attname = 'refuri' + call_method = None + else: + return + attval = target[attname] + for name in target['names']: + reflist = self.document.refnames.get(name, []) + if reflist: + target.note_referenced_by(name=name) + for ref in reflist: + if ref.resolved: + continue + del ref['refname'] + ref[attname] = attval + if call_method: + call_method(ref) + ref.resolved = 1 + if isinstance(ref, nodes.target): + self.resolve_indirect_references(ref) + for id in target['ids']: + reflist = self.document.refids.get(id, []) + if reflist: + target.note_referenced_by(id=id) + for ref in reflist: + if ref.resolved: + continue + del ref['refid'] + ref[attname] = attval + if call_method: + call_method(ref) + ref.resolved = 1 + if isinstance(ref, nodes.target): + self.resolve_indirect_references(ref) + + +class ExternalTargets(Transform): + + """ + Given:: + + <paragraph> + <reference refname="direct external"> + direct external + <target id="id1" name="direct external" refuri="http://direct"> + + The "refname" attribute is replaced by the direct "refuri" attribute:: + + <paragraph> + <reference refuri="http://direct"> + direct external + <target id="id1" name="direct external" refuri="http://direct"> + """ + + default_priority = 640 + + def apply(self): + for target in self.document.traverse(nodes.target): + if target.hasattr('refuri'): + refuri = target['refuri'] + for name in target['names']: + reflist = self.document.refnames.get(name, []) + if reflist: + target.note_referenced_by(name=name) + for ref in reflist: + if ref.resolved: + continue + del ref['refname'] + ref['refuri'] = refuri + ref.resolved = 1 + + +class InternalTargets(Transform): + + default_priority = 660 + + def apply(self): + for target in self.document.traverse(nodes.target): + if not target.hasattr('refuri') and not target.hasattr('refid'): + self.resolve_reference_ids(target) + + def resolve_reference_ids(self, target): + """ + Given:: + + <paragraph> + <reference refname="direct internal"> + direct internal + <target id="id1" name="direct internal"> + + The "refname" attribute is replaced by "refid" linking to the target's + "id":: + + <paragraph> + <reference refid="id1"> + direct internal + <target id="id1" name="direct internal"> + """ + for name in target['names']: + refid = self.document.nameids.get(name) + reflist = self.document.refnames.get(name, []) + if reflist: + target.note_referenced_by(name=name) + for ref in reflist: + if ref.resolved: + continue + if refid: + del ref['refname'] + ref['refid'] = refid + ref.resolved = 1 + + +class Footnotes(Transform): + + """ + Assign numbers to autonumbered footnotes, and resolve links to footnotes, + citations, and their references. + + Given the following ``document`` as input:: + + <document> + <paragraph> + A labeled autonumbered footnote referece: + <footnote_reference auto="1" id="id1" refname="footnote"> + <paragraph> + An unlabeled autonumbered footnote referece: + <footnote_reference auto="1" id="id2"> + <footnote auto="1" id="id3"> + <paragraph> + Unlabeled autonumbered footnote. + <footnote auto="1" id="footnote" name="footnote"> + <paragraph> + Labeled autonumbered footnote. + + Auto-numbered footnotes have attribute ``auto="1"`` and no label. + Auto-numbered footnote_references have no reference text (they're + empty elements). When resolving the numbering, a ``label`` element + is added to the beginning of the ``footnote``, and reference text + to the ``footnote_reference``. + + The transformed result will be:: + + <document> + <paragraph> + A labeled autonumbered footnote referece: + <footnote_reference auto="1" id="id1" refid="footnote"> + 2 + <paragraph> + An unlabeled autonumbered footnote referece: + <footnote_reference auto="1" id="id2" refid="id3"> + 1 + <footnote auto="1" id="id3" backrefs="id2"> + <label> + 1 + <paragraph> + Unlabeled autonumbered footnote. + <footnote auto="1" id="footnote" name="footnote" backrefs="id1"> + <label> + 2 + <paragraph> + Labeled autonumbered footnote. + + Note that the footnotes are not in the same order as the references. + + The labels and reference text are added to the auto-numbered ``footnote`` + and ``footnote_reference`` elements. Footnote elements are backlinked to + their references via "refids" attributes. References are assigned "id" + and "refid" attributes. + + After adding labels and reference text, the "auto" attributes can be + ignored. + """ + + default_priority = 620 + + autofootnote_labels = None + """Keep track of unlabeled autonumbered footnotes.""" + + symbols = [ + # Entries 1-4 and 6 below are from section 12.51 of + # The Chicago Manual of Style, 14th edition. + '*', # asterisk/star + u'\u2020', # dagger † + u'\u2021', # double dagger ‡ + u'\u00A7', # section mark § + u'\u00B6', # paragraph mark (pilcrow) ¶ + # (parallels ['||'] in CMoS) + '#', # number sign + # The entries below were chosen arbitrarily. + u'\u2660', # spade suit ♠ + u'\u2665', # heart suit ♥ + u'\u2666', # diamond suit ♦ + u'\u2663', # club suit ♣ + ] + + def apply(self): + self.autofootnote_labels = [] + startnum = self.document.autofootnote_start + self.document.autofootnote_start = self.number_footnotes(startnum) + self.number_footnote_references(startnum) + self.symbolize_footnotes() + self.resolve_footnotes_and_citations() + + def number_footnotes(self, startnum): + """ + Assign numbers to autonumbered footnotes. + + For labeled autonumbered footnotes, copy the number over to + corresponding footnote references. + """ + for footnote in self.document.autofootnotes: + while True: + label = str(startnum) + startnum += 1 + if label not in self.document.nameids: + break + footnote.insert(0, nodes.label('', label)) + for name in footnote['names']: + for ref in self.document.footnote_refs.get(name, []): + ref += nodes.Text(label) + ref.delattr('refname') + assert len(footnote['ids']) == len(ref['ids']) == 1 + ref['refid'] = footnote['ids'][0] + footnote.add_backref(ref['ids'][0]) + self.document.note_refid(ref) + ref.resolved = 1 + if not footnote['names'] and not footnote['dupnames']: + footnote['names'].append(label) + self.document.note_explicit_target(footnote, footnote) + self.autofootnote_labels.append(label) + return startnum + + def number_footnote_references(self, startnum): + """Assign numbers to autonumbered footnote references.""" + i = 0 + for ref in self.document.autofootnote_refs: + if ref.resolved or ref.hasattr('refid'): + continue + try: + label = self.autofootnote_labels[i] + except IndexError: + msg = self.document.reporter.error( + 'Too many autonumbered footnote references: only %s ' + 'corresponding footnotes available.' + % len(self.autofootnote_labels), base_node=ref) + msgid = self.document.set_id(msg) + for ref in self.document.autofootnote_refs[i:]: + if ref.resolved or ref.hasattr('refname'): + continue + prb = nodes.problematic( + ref.rawsource, ref.rawsource, refid=msgid) + prbid = self.document.set_id(prb) + msg.add_backref(prbid) + ref.replace_self(prb) + break + ref += nodes.Text(label) + id = self.document.nameids[label] + footnote = self.document.ids[id] + ref['refid'] = id + self.document.note_refid(ref) + assert len(ref['ids']) == 1 + footnote.add_backref(ref['ids'][0]) + ref.resolved = 1 + i += 1 + + def symbolize_footnotes(self): + """Add symbols indexes to "[*]"-style footnotes and references.""" + labels = [] + for footnote in self.document.symbol_footnotes: + reps, index = divmod(self.document.symbol_footnote_start, + len(self.symbols)) + labeltext = self.symbols[index] * (reps + 1) + labels.append(labeltext) + footnote.insert(0, nodes.label('', labeltext)) + self.document.symbol_footnote_start += 1 + self.document.set_id(footnote) + i = 0 + for ref in self.document.symbol_footnote_refs: + try: + ref += nodes.Text(labels[i]) + except IndexError: + msg = self.document.reporter.error( + 'Too many symbol footnote references: only %s ' + 'corresponding footnotes available.' % len(labels), + base_node=ref) + msgid = self.document.set_id(msg) + for ref in self.document.symbol_footnote_refs[i:]: + if ref.resolved or ref.hasattr('refid'): + continue + prb = nodes.problematic( + ref.rawsource, ref.rawsource, refid=msgid) + prbid = self.document.set_id(prb) + msg.add_backref(prbid) + ref.replace_self(prb) + break + footnote = self.document.symbol_footnotes[i] + assert len(footnote['ids']) == 1 + ref['refid'] = footnote['ids'][0] + self.document.note_refid(ref) + footnote.add_backref(ref['ids'][0]) + i += 1 + + def resolve_footnotes_and_citations(self): + """ + Link manually-labeled footnotes and citations to/from their + references. + """ + for footnote in self.document.footnotes: + for label in footnote['names']: + if label in self.document.footnote_refs: + reflist = self.document.footnote_refs[label] + self.resolve_references(footnote, reflist) + for citation in self.document.citations: + for label in citation['names']: + if label in self.document.citation_refs: + reflist = self.document.citation_refs[label] + self.resolve_references(citation, reflist) + + def resolve_references(self, note, reflist): + assert len(note['ids']) == 1 + id = note['ids'][0] + for ref in reflist: + if ref.resolved: + continue + ref.delattr('refname') + ref['refid'] = id + assert len(ref['ids']) == 1 + note.add_backref(ref['ids'][0]) + ref.resolved = 1 + note.resolved = 1 + + +class CircularSubstitutionDefinitionError(Exception): pass + + +class Substitutions(Transform): + + """ + Given the following ``document`` as input:: + + <document> + <paragraph> + The + <substitution_reference refname="biohazard"> + biohazard + symbol is deservedly scary-looking. + <substitution_definition name="biohazard"> + <image alt="biohazard" uri="biohazard.png"> + + The ``substitution_reference`` will simply be replaced by the + contents of the corresponding ``substitution_definition``. + + The transformed result will be:: + + <document> + <paragraph> + The + <image alt="biohazard" uri="biohazard.png"> + symbol is deservedly scary-looking. + <substitution_definition name="biohazard"> + <image alt="biohazard" uri="biohazard.png"> + """ + + default_priority = 220 + """The Substitutions transform has to be applied very early, before + `docutils.tranforms.frontmatter.DocTitle` and others.""" + + def apply(self): + defs = self.document.substitution_defs + normed = self.document.substitution_names + subreflist = self.document.traverse(nodes.substitution_reference) + nested = {} + for ref in subreflist: + refname = ref['refname'] + key = None + if refname in defs: + key = refname + else: + normed_name = refname.lower() + if normed_name in normed: + key = normed[normed_name] + if key is None: + msg = self.document.reporter.error( + 'Undefined substitution referenced: "%s".' + % refname, base_node=ref) + msgid = self.document.set_id(msg) + prb = nodes.problematic( + ref.rawsource, ref.rawsource, refid=msgid) + prbid = self.document.set_id(prb) + msg.add_backref(prbid) + ref.replace_self(prb) + else: + subdef = defs[key] + parent = ref.parent + index = parent.index(ref) + if ('ltrim' in subdef.attributes + or 'trim' in subdef.attributes): + if index > 0 and isinstance(parent[index - 1], + nodes.Text): + parent.replace(parent[index - 1], + parent[index - 1].rstrip()) + if ('rtrim' in subdef.attributes + or 'trim' in subdef.attributes): + if (len(parent) > index + 1 + and isinstance(parent[index + 1], nodes.Text)): + parent.replace(parent[index + 1], + parent[index + 1].lstrip()) + subdef_copy = subdef.deepcopy() + try: + # Take care of nested substitution references: + for nested_ref in subdef_copy.traverse( + nodes.substitution_reference): + nested_name = normed[nested_ref['refname'].lower()] + if nested_name in nested.setdefault(nested_name, []): + raise CircularSubstitutionDefinitionError + else: + nested[nested_name].append(key) + nested_ref['ref-origin'] = ref + subreflist.append(nested_ref) + except CircularSubstitutionDefinitionError: + parent = ref.parent + if isinstance(parent, nodes.substitution_definition): + msg = self.document.reporter.error( + 'Circular substitution definition detected:', + nodes.literal_block(parent.rawsource, + parent.rawsource), + line=parent.line, base_node=parent) + parent.replace_self(msg) + else: + # find original ref substitution which cased this error + ref_origin = ref + while ref_origin.hasattr('ref-origin'): + ref_origin = ref_origin['ref-origin'] + msg = self.document.reporter.error( + 'Circular substitution definition referenced: ' + '"%s".' % refname, base_node=ref_origin) + msgid = self.document.set_id(msg) + prb = nodes.problematic( + ref.rawsource, ref.rawsource, refid=msgid) + prbid = self.document.set_id(prb) + msg.add_backref(prbid) + ref.replace_self(prb) + else: + ref.replace_self(subdef_copy.children) + # register refname of the replacment node(s) + # (needed for resolution of references) + for node in subdef_copy.children: + if isinstance(node, nodes.Referential): + # HACK: verify refname attribute exists. + # Test with docs/dev/todo.txt, see. |donate| + if 'refname' in node: + self.document.note_refname(node) + + +class TargetNotes(Transform): + + """ + Creates a footnote for each external target in the text, and corresponding + footnote references after each reference. + """ + + default_priority = 540 + """The TargetNotes transform has to be applied after `IndirectHyperlinks` + but before `Footnotes`.""" + + + def __init__(self, document, startnode): + Transform.__init__(self, document, startnode=startnode) + + self.classes = startnode.details.get('class', []) + + def apply(self): + notes = {} + nodelist = [] + for target in self.document.traverse(nodes.target): + # Only external targets. + if not target.hasattr('refuri'): + continue + names = target['names'] + refs = [] + for name in names: + refs.extend(self.document.refnames.get(name, [])) + if not refs: + continue + footnote = self.make_target_footnote(target['refuri'], refs, + notes) + if target['refuri'] not in notes: + notes[target['refuri']] = footnote + nodelist.append(footnote) + # Take care of anonymous references. + for ref in self.document.traverse(nodes.reference): + if not ref.get('anonymous'): + continue + if ref.hasattr('refuri'): + footnote = self.make_target_footnote(ref['refuri'], [ref], + notes) + if ref['refuri'] not in notes: + notes[ref['refuri']] = footnote + nodelist.append(footnote) + self.startnode.replace_self(nodelist) + + def make_target_footnote(self, refuri, refs, notes): + if refuri in notes: # duplicate? + footnote = notes[refuri] + assert len(footnote['names']) == 1 + footnote_name = footnote['names'][0] + else: # original + footnote = nodes.footnote() + footnote_id = self.document.set_id(footnote) + # Use uppercase letters and a colon; they can't be + # produced inside names by the parser. + footnote_name = 'TARGET_NOTE: ' + footnote_id + footnote['auto'] = 1 + footnote['names'] = [footnote_name] + footnote_paragraph = nodes.paragraph() + footnote_paragraph += nodes.reference('', refuri, refuri=refuri) + footnote += footnote_paragraph + self.document.note_autofootnote(footnote) + self.document.note_explicit_target(footnote, footnote) + for ref in refs: + if isinstance(ref, nodes.target): + continue + refnode = nodes.footnote_reference(refname=footnote_name, auto=1) + refnode['classes'] += self.classes + self.document.note_autofootnote_ref(refnode) + self.document.note_footnote_ref(refnode) + index = ref.parent.index(ref) + 1 + reflist = [refnode] + if not utils.get_trim_footnote_ref_space(self.document.settings): + if self.classes: + reflist.insert(0, nodes.inline(text=' ', Classes=self.classes)) + else: + reflist.insert(0, nodes.Text(' ')) + ref.parent.insert(index, reflist) + return footnote + + +class DanglingReferences(Transform): + + """ + Check for dangling references (incl. footnote & citation) and for + unreferenced targets. + """ + + default_priority = 850 + + def apply(self): + visitor = DanglingReferencesVisitor( + self.document, + self.document.transformer.unknown_reference_resolvers) + self.document.walk(visitor) + # *After* resolving all references, check for unreferenced + # targets: + for target in self.document.traverse(nodes.target): + if not target.referenced: + if target.get('anonymous'): + # If we have unreferenced anonymous targets, there + # is already an error message about anonymous + # hyperlink mismatch; no need to generate another + # message. + continue + if target['names']: + naming = target['names'][0] + elif target['ids']: + naming = target['ids'][0] + else: + # Hack: Propagated targets always have their refid + # attribute set. + naming = target['refid'] + self.document.reporter.info( + 'Hyperlink target "%s" is not referenced.' + % naming, base_node=target) + + +class DanglingReferencesVisitor(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 + + def visit_reference(self, node): + if node.resolved or not node.hasattr('refname'): + return + refname = node['refname'] + id = self.document.nameids.get(refname) + if id is None: + for resolver_function in self.unknown_reference_resolvers: + if resolver_function(node): + break + else: + if refname in self.document.nameids: + 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) + try: + prbid = node['ids'][0] + except IndexError: + prbid = self.document.set_id(prb) + msg.add_backref(prbid) + node.replace_self(prb) + else: + del node['refname'] + node['refid'] = id + self.document.ids[id].note_referenced_by(id=id) + node.resolved = 1 + + visit_footnote_reference = visit_citation_reference = visit_reference diff --git a/docutils/transforms/universal.py b/docutils/transforms/universal.py new file mode 100644 index 0000000..40036c0 --- /dev/null +++ b/docutils/transforms/universal.py @@ -0,0 +1,311 @@ +# $Id: universal.py 8144 2017-07-26 21:25:08Z milde $ +# -*- coding: utf-8 -*- +# Authors: David Goodger <goodger@python.org>; Ueli Schlaepfer; Günter Milde +# Maintainer: docutils-develop@lists.sourceforge.net +# Copyright: This module has been placed in the public domain. + +""" +Transforms needed by most or all documents: + +- `Decorations`: Generate a document's header & footer. +- `Messages`: Placement of system messages stored in + `nodes.document.transform_messages`. +- `TestMessages`: Like `Messages`, used on test runs. +- `FinalReferences`: Resolve remaining references. +""" + +__docformat__ = 'reStructuredText' + +import re +import sys +import time +from docutils import nodes, utils +from docutils.transforms import TransformError, Transform +from docutils.utils import smartquotes + +class Decorations(Transform): + + """ + Populate a document's decoration element (header, footer). + """ + + default_priority = 820 + + def apply(self): + header_nodes = self.generate_header() + if header_nodes: + decoration = self.document.get_decoration() + header = decoration.get_header() + header.extend(header_nodes) + footer_nodes = self.generate_footer() + if footer_nodes: + decoration = self.document.get_decoration() + footer = decoration.get_footer() + footer.extend(footer_nodes) + + def generate_header(self): + return None + + def generate_footer(self): + # @@@ Text is hard-coded for now. + # Should be made dynamic (language-dependent). + # @@@ Use timestamp from the `SOURCE_DATE_EPOCH`_ environment variable + # for the datestamp? + # See https://sourceforge.net/p/docutils/patches/132/ + # and https://reproducible-builds.org/specs/source-date-epoch/ + settings = self.document.settings + if settings.generator or settings.datestamp or settings.source_link \ + or settings.source_url: + text = [] + if settings.source_link and settings._source \ + or settings.source_url: + if settings.source_url: + source = settings.source_url + else: + source = utils.relative_path(settings._destination, + settings._source) + text.extend([ + nodes.reference('', 'View document source', + refuri=source), + nodes.Text('.\n')]) + if settings.datestamp: + datestamp = time.strftime(settings.datestamp, time.gmtime()) + text.append(nodes.Text('Generated on: ' + datestamp + '.\n')) + if settings.generator: + text.extend([ + nodes.Text('Generated by '), + nodes.reference('', 'Docutils', refuri= + 'http://docutils.sourceforge.net/'), + nodes.Text(' from '), + nodes.reference('', 'reStructuredText', refuri='http://' + 'docutils.sourceforge.net/rst.html'), + nodes.Text(' source.\n')]) + return [nodes.paragraph('', '', *text)] + else: + return None + + +class ExposeInternals(Transform): + + """ + Expose internal attributes if ``expose_internals`` setting is set. + """ + + default_priority = 840 + + def not_Text(self, node): + return not isinstance(node, nodes.Text) + + def apply(self): + if self.document.settings.expose_internals: + for node in self.document.traverse(self.not_Text): + for att in self.document.settings.expose_internals: + value = getattr(node, att, None) + if value is not None: + node['internal:' + att] = value + + +class Messages(Transform): + + """ + Place any system messages generated after parsing into a dedicated section + of the document. + """ + + default_priority = 860 + + def apply(self): + unfiltered = self.document.transform_messages + threshold = self.document.reporter.report_level + messages = [] + for msg in unfiltered: + if msg['level'] >= threshold and not msg.parent: + messages.append(msg) + if messages: + section = nodes.section(classes=['system-messages']) + # @@@ get this from the language module? + section += nodes.title('', 'Docutils System Messages') + section += messages + self.document.transform_messages[:] = [] + self.document += section + + +class FilterMessages(Transform): + + """ + Remove system messages below verbosity threshold. + """ + + default_priority = 870 + + def apply(self): + for node in self.document.traverse(nodes.system_message): + if node['level'] < self.document.reporter.report_level: + node.parent.remove(node) + + +class TestMessages(Transform): + + """ + Append all post-parse system messages to the end of the document. + + Used for testing purposes. + """ + + default_priority = 880 + + def apply(self): + for msg in self.document.transform_messages: + if not msg.parent: + self.document += msg + + +class StripComments(Transform): + + """ + Remove comment elements from the document tree (only if the + ``strip_comments`` setting is enabled). + """ + + default_priority = 740 + + def apply(self): + if self.document.settings.strip_comments: + for node in self.document.traverse(nodes.comment): + node.parent.remove(node) + + +class StripClassesAndElements(Transform): + + """ + Remove from the document tree all elements with classes in + `self.document.settings.strip_elements_with_classes` and all "classes" + attribute values in `self.document.settings.strip_classes`. + """ + + default_priority = 420 + + def apply(self): + if not (self.document.settings.strip_elements_with_classes + or self.document.settings.strip_classes): + return + # prepare dicts for lookup (not sets, for Python 2.2 compatibility): + self.strip_elements = dict( + [(key, None) + for key in (self.document.settings.strip_elements_with_classes + or [])]) + self.strip_classes = dict( + [(key, None) for key in (self.document.settings.strip_classes + or [])]) + for node in self.document.traverse(self.check_classes): + node.parent.remove(node) + + def check_classes(self, node): + if isinstance(node, nodes.Element): + for class_value in node['classes'][:]: + if class_value in self.strip_classes: + node['classes'].remove(class_value) + if class_value in self.strip_elements: + return 1 + + +class SmartQuotes(Transform): + + """ + Replace ASCII quotation marks with typographic form. + + Also replace multiple dashes with em-dash/en-dash characters. + """ + + default_priority = 850 + + nodes_to_skip = (nodes.FixedTextElement, nodes.Special) + """Do not apply "smartquotes" to instances of these block-level nodes.""" + + literal_nodes = (nodes.image, nodes.literal, nodes.math, + nodes.raw, nodes.problematic) + """Do not change quotes in instances of these inline nodes.""" + + smartquotes_action = 'qDe' + """Setting to select smartquote transformations. + + The default 'qDe' educates normal quote characters: (", '), + em- and en-dashes (---, --) and ellipses (...). + """ + + def __init__(self, document, startnode): + Transform.__init__(self, document, startnode=startnode) + self.unsupported_languages = set() + + def get_tokens(self, txtnodes): + # A generator that yields ``(texttype, nodetext)`` tuples for a list + # of "Text" nodes (interface to ``smartquotes.educate_tokens()``). + + texttype = {True: 'literal', # "literal" text is not changed: + False: 'plain'} + for txtnode in txtnodes: + nodetype = texttype[isinstance(txtnode.parent, + self.literal_nodes)] + yield (nodetype, txtnode.astext()) + + + def apply(self): + smart_quotes = self.document.settings.smart_quotes + if not smart_quotes: + return + try: + alternative = smart_quotes.startswith('alt') + except AttributeError: + alternative = False + # print repr(alternative) + + document_language = self.document.settings.language_code + lc_smartquotes = self.document.settings.smartquotes_locales + if lc_smartquotes: + smartquotes.smartchars.quotes.update(dict(lc_smartquotes)) + + # "Educate" quotes in normal text. Handle each block of text + # (TextElement node) as a unit to keep context around inline nodes: + for node in self.document.traverse(nodes.TextElement): + # skip preformatted text blocks and special elements: + if isinstance(node, self.nodes_to_skip): + continue + # nested TextElements are not "block-level" elements: + if isinstance(node.parent, nodes.TextElement): + continue + + # list of text nodes in the "text block": + txtnodes = [txtnode for txtnode in node.traverse(nodes.Text) + if not isinstance(txtnode.parent, + nodes.option_string)] + + # language: use typographical quotes for language "lang" + lang = node.get_language_code(document_language) + # use alternative form if `smart-quotes` setting starts with "alt": + if alternative: + if '-x-altquot' in lang: + lang = lang.replace('-x-altquot', '') + else: + lang += '-x-altquot' + # drop unsupported subtags: + for tag in utils.normalize_language_tag(lang): + if tag in smartquotes.smartchars.quotes: + lang = tag + break + else: # language not supported: (keep ASCII quotes) + if lang not in self.unsupported_languages: + self.document.reporter.warning('No smart quotes ' + 'defined for language "%s".'%lang, base_node=node) + self.unsupported_languages.add(lang) + lang = '' + + # Iterator educating quotes in plain text: + # (see "utils/smartquotes.py" for the attribute setting) + teacher = smartquotes.educate_tokens(self.get_tokens(txtnodes), + attr=self.smartquotes_action, language=lang) + + for txtnode, newtext in zip(txtnodes, teacher): + txtnode.parent.replace(txtnode, nodes.Text(newtext, + rawsource=txtnode.rawsource)) + + self.unsupported_languages = set() # reset diff --git a/docutils/transforms/writer_aux.py b/docutils/transforms/writer_aux.py new file mode 100644 index 0000000..c5818d9 --- /dev/null +++ b/docutils/transforms/writer_aux.py @@ -0,0 +1,88 @@ +# $Id: writer_aux.py 7808 2015-02-27 17:03:32Z milde $ +# Author: Lea Wiemann <LeWiemann@gmail.com> +# Copyright: This module has been placed in the public domain. + +""" +Auxiliary transforms mainly to be used by Writer components. + +This module is called "writer_aux" because otherwise there would be +conflicting imports like this one:: + + from docutils import writers + from docutils.transforms import writers +""" + +__docformat__ = 'reStructuredText' + +from docutils import nodes, utils, languages +from docutils.transforms import Transform + + +class Compound(Transform): + + """ + Flatten all compound paragraphs. For example, transform :: + + <compound> + <paragraph> + <literal_block> + <paragraph> + + into :: + + <paragraph> + <literal_block classes="continued"> + <paragraph classes="continued"> + """ + + default_priority = 910 + + def apply(self): + for compound in self.document.traverse(nodes.compound): + first_child = True + for child in compound: + if first_child: + if not isinstance(child, nodes.Invisible): + first_child = False + else: + child['classes'].append('continued') + # Substitute children for compound. + compound.replace_self(compound[:]) + + +class Admonitions(Transform): + + """ + Transform specific admonitions, like this: + + <note> + <paragraph> + Note contents ... + + into generic admonitions, like this:: + + <admonition classes="note"> + <title> + Note + <paragraph> + Note contents ... + + The admonition title is localized. + """ + + default_priority = 920 + + def apply(self): + language = languages.get_language(self.document.settings.language_code, + self.document.reporter) + for node in self.document.traverse(nodes.Admonition): + node_name = node.__class__.__name__ + # Set class, so that we know what node this admonition came from. + node['classes'].append(node_name) + if not isinstance(node, nodes.admonition): + # Specific admonition. Transform into a generic admonition. + admonition = nodes.admonition(node.rawsource, *node.children, + **node.attributes) + title = nodes.title('', language.labels[node_name]) + admonition.insert(0, title) + node.replace_self(admonition)